Presentes com significado, no seu site
Seus criadores recebem presentes animados, com raridade, nome de quem enviou e recado, em vez de um valor solto. E, se o criador faz live, o presente aparece na transmissão, como nos alertas do LivePix, mas com muito mais simbologia.
Você não precisa de CNPJ, de conta em gateway nem de checkout próprio: o bday.fm cobra por Pix, avisa o seu servidor e você fica com 5% de cada presente.
Como o dinheiro funciona
paid.De cada presente, o valor pago pelo fã é dividido assim (padrão atual):
Repasse que você credita ao criador no seu site.
Sua comissão, paga com parte da taxa do bday.fm.
Taxa da plataforma, já sem a sua comissão.
O repasse do criador e a sua comissão entram juntos no seu saldo bday.fm, em bday.fm/carteira, discriminados como “Repasse de criador (parceiro)” e “Comissão de parceiro”. Como o seu saldo recebe os dois valores, é você quem paga o criador dentro do seu site.
- Retenção: cada valor fica retido por alguns dias (padrão: 7) antes de poder ser sacado. Ele já aparece no saldo, mas protege contra devolução do Pix.
- Saque: para a chave Pix da sua conta, que fica presa ao cadastro por segurança. O dinheiro chega em até 48 horas úteis. É preciso ter a identidade verificada.
- Devolução: se um Pix for devolvido, você recebe o webhook
gift.refundede o valor é revertido do seu saldo. Desfaça o crédito do criador no seu site.
GET /api/v1/me devolve as regras vigentes (split e hold_days), e cada webhook já traz os valores exatos em centavos.Virar parceiro
Qualquer site pode pedir adesão. Você precisa de uma conta no bday.fm (é ela que recebe o saldo) e faz a solicitação em três passos em bday.fm/parceiro:
- O site: nome, endereço (https) onde o modal será instalado e uma descrição do site, do público e do tipo de conteúdo que ele publica.
- Termos e privacidade: os endereços (https) dos termos de uso e da política de privacidade do seu site, mais o aceite dos termos de parceria.
- Recebimento: saldo na sua carteira bday.fm com saque por Pix, e um e-mail de contato para os avisos.
O time do bday.fm avalia o pedido. Se for aprovado, as chaves e o segredo do webhook são criados sozinhos e o endereço do receptor já vem preenchido no seu domínio. Se não for, você recebe o motivo, pode ajustar o que for preciso e solicitar de novo, quantas vezes quiser.
Vários sites na mesma conta
Uma conta do bday.fm pode ter quantos sites quiser (até 10 pedidos ao mesmo tempo). Cada site é uma parceria à parte: é avaliado, aprovado, suspenso e configurado sozinho, com as próprias chaves, criadores e endereço de webhook. O que é um só é o saldo: a comissão e o repasse de todos os sites caem na mesma carteira da conta. O mesmo domínio não pode estar em duas parcerias.
Tudo isso fica em Ajustes (menu do seu nome, no canto superior direito) → Parcerias e lives: candidatar um novo site, acompanhar pedidos, reenviar um pedido recusado e abrir o painel de cada site ou o extrato consolidado.
O que é avaliado
- O site tem termos de uso e política de privacidade próprios, públicos e acessíveis.
- O conteúdo e o público descritos estão de acordo com a lei brasileira e com as políticas do bday.fm.
- O domínio informado é seu. O modal só abre nos domínios aprovados (o do site, com e sem
www, mais até 4 extras que você informar).
Começo rápido
Com o pedido aprovado, abra bday.fm/parceiro e vá em Integração. Tudo já está preenchido para o seu site: chave pública, chave de teste, segredo do webhook e o endereço do receptor.
1. Coloque o botão no seu site
<script src="https://bday.fm/embed.js" data-key="pk_live_SUA_CHAVE" async></script>
<button data-bday-gift
data-creator-ref="ID_DO_CRIADOR"
data-creator-name="Nome do criador"
data-creator-avatar="https://.../foto.jpg">
Enviar presente
</button>
data-creator-ref é o id do criador no seu sistema. Ele volta para você no webhook, para você saber quem creditar.
2. Instale o receptor do webhook
É uma rota no seu servidor que confere a assinatura e recebe o aviso. O painel entrega o código pronto (Node, Next.js e PHP), e há um exemplo em Python mais abaixo. A única parte sua é somar o valor ao saldo do criador. Guarde o segredo numa variável de ambiente (BDAY_WEBHOOK_SECRET), nunca no código.
3. Teste sem gastar nada
No painel, mude o alternador para Teste, use o snippet com a chave pk_test_... e envie um presente: em vez de cobrar um Pix, o modal mostra “Simular pagamento aprovado”, e o seu receptor recebe o webhook de verdade. Veja Modo de teste.
4. Vá para produção
Troque a chave de teste pela chave real (pk_live_...) e pronto. Confira o checklist.
Modo de teste
O modo de teste percorre exatamente o mesmo caminho do pagamento real (estados, webhook assinado, criador, overlay), sem cobrar Pix e sem mexer em nenhum saldo. É o jeito de terminar a integração sem gastar dinheiro e sem aparecer para o público.
| Real | Teste | |
|---|---|---|
| Chave pública (modal) | pk_live_... | pk_test_... |
| Chave secreta (API) | sk_live_... | sk_test_... |
| Cobra Pix? | Sim | Não |
| Mexe no saldo? | Sim | Nunca |
| Envia webhook? | Sim | Sim, com "livemode": false |
| Segredo do webhook | O mesmo nos dois modos: o seu receptor não muda | |
| Criadores, presentes e overlay | Separados: criador de teste só enxerga presentes de teste | |
Como “pagar” um presente de teste
- No modal ou no link do criador: o botão Simular pagamento aprovado aparece no lugar do QR Code.
- No painel: em Transações (modo Teste), abra o presente e clique em Simular estorno para receber o
gift.refunded. - Pela API (com
sk_test_):POST /api/v1/gifts/{id}/simulatecom{"event": "paid"}ou{"event": "refunded"}.
livemode no seu receptor. Um webhook de teste chega no mesmo endereço e com a mesma assinatura de um real. Se livemode for false, registre para conferir, mas não credite saldo real a um criador.Modal de presentes
O embed.js abre uma janela por cima da sua página. O fã escolhe o presente (com arte, animação, descrição, raridade e valor), informa nome, e-mail e recado e paga por Pix, tudo sem sair do seu site. O e-mail é exigido pelo Pix e nunca é enviado ao parceiro.
Botão sem JavaScript
| Atributo | Obrigatório | Descrição |
|---|---|---|
data-bday-gift | sim | Marca o elemento que abre o modal ao ser clicado. |
data-creator-ref | sim | Id do criador no seu sistema (até 80 caracteres). Volta no webhook como recipient.ref. |
data-creator-name | sim | Nome que o fã vê (“Presentear ...”). |
data-creator-avatar | não | Foto do criador, precisa ser https. |
Por JavaScript
BdayGifts.open({
creatorRef: 'ID_DO_CRIADOR',
creatorName: 'Nome do criador',
creatorAvatar: 'https://.../foto.jpg', // opcional
onSuccess: function (d) {
// d.transactionId, d.creatorRef, d.giftId, d.giftName, d.amountCents
},
onClose: function () {} // opcional
});
BdayGifts.close(); // fecha por código
BdayGifts.init({ key: 'pk_live_SUA_CHAVE' }); // alternativa ao data-key do script
onSuccess. Ele vem do navegador do fã e serve só para mostrar um “obrigado” ou atualizar a tela. O crédito deve acontecer somente pelo webhook, que é assinado.Requisitos
- Domínios: o modal só abre em domínios aprovados no seu pedido. Em outro site, o navegador bloqueia.
- Política de segurança (CSP): se o seu site usa CSP, libere
script-src https://bday.fmeframe-src https://bday.fm. - Celular: o modal ocupa a tela toda. Nenhum ajuste é necessário.
- Segurança: a chave pública (
pk_...) pode ficar no HTML. Ela só abre o modal e nunca movimenta nada sozinha.
Criadores e link de presente
Cada criador do seu site ganha, sem você montar nada:
- Link de presente (
https://bday.fm/c/abc123xyz9): a mesma tela do modal, em página inteira. Serve para a bio, o chat da live (por exemplo, um comando!presente) ou um QR Code na tela. Funciona até para quem não tem o modal instalado. - QR Code e cartaz desse link, para a tela da live e para imprimir. Veja QR Code e cartaz.
- Três fontes para o OBS (
https://bday.fm/overlay/ov_...): o alerta de presente, a barra de meta em tempo real e o QR Code fixo na tela.
Como o criador é cadastrado
- Sozinho: no primeiro presente pago, o criador já aparece no painel com os dois links.
- Pela API: cadastre antes do primeiro presente e mostre os links no painel do seu site.
- No painel: aba Criadores e live, seção “Cadastrar criador”.
curl -X PUT https://bday.fm/api/v1/creators/ID_DO_CRIADOR \
-H "Authorization: Bearer sk_live_SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{"name": "Nome do criador", "avatar_url": "https://.../foto.jpg"}'
A resposta traz todos os endereços do criador (gift_page_url, overlay_url, goal_overlay_url, qr_overlay_url, qr_code_url e poster_url). O nome e a foto só mudam por aqui (o modal, por ser público, nunca altera um criador já cadastrado).
Overlay de live (OBS)
É uma das três fontes da live (as outras são a barra de meta e o QR Code). Ela faz o presente aparecer na transmissão: o presente animado, na cor da raridade, com “Ana enviou Lua de Presente”, o recado e um aviso sonoro. Vários presentes seguidos entram numa fila. O fundo é transparente.
Configurar no OBS (leva 1 minuto)
- Em Fontes, clique em + e escolha Navegador.
- Em URL, cole o
overlay_urldo criador. - Largura 1280 e altura 720 (ou o tamanho da sua cena).
- Marque Controlar áudio via OBS se quiser ajustar o aviso sonoro na mesa de áudio.
- Para posicionar, acrescente
?preview=1ao endereço: um alerta de exemplo aparece a cada 10 segundos. Remova o?preview=1antes de entrar ao vivo.
É uma página web comum: qualquer programa de live com “fonte de navegador” (OBS Studio, Streamlabs e similares) consegue exibi-la.
Ajustes pelo endereço
| Parâmetro | Padrão | O que faz |
|---|---|---|
preview=1 | — | Mostra um alerta de exemplo a cada 10 s, para posicionar. |
rarity=lendario | — | Com preview: só exemplos dessa raridade (comum, raro, epico, lendario). |
dur=9 | 9 | Segundos na tela (4 a 30). Recados longos ficam um pouco mais. |
vol=0.5 | 0.5 | Volume do aviso sonoro (0 a 1). Use 0 para silenciar. |
scale=1 | 1 | Tamanho do alerta (0.4 a 3). |
pos=bottom | bottom | Posição: top, center ou bottom. |
min=1000 | 0 | Só mostra presentes a partir desse valor, em centavos. |
msg=0 | mostra | Esconde o recado (moderação). |
valor=1 | esconde | Mostra o valor do presente. |
Exemplo: https://bday.fm/overlay/ov_...?pos=top&vol=0.3&min=500
POST /api/v1/creators/{ref}/overlay/rotate. O link antigo para de funcionar na hora.msg=0 se o criador preferir não exibir recados na live.Meta em tempo real
Uma barra que mostra, na própria live, quanto já foi arrecadado de uma meta (“Novo microfone: R$ 1.000”). Ela enche a cada presente pago, com o valor subindo na tela, e fica dourada com uma comemoração quando a meta é batida.
Como definir
- No painel: Criadores e live → Preparar live → Meta: título e valor em reais.
- Pela API:
PUT /api/v1/creators/{ref}/goal.
Regras
- Conta o valor pago pelos fãs (o
gross_centsdo presente), só dos presentes pagos depois que a meta começou. - Se um Pix é devolvido, o valor sai da barra sozinho: o progresso é sempre calculado dos presentes pagos, nunca guardado.
- Cada criador tem uma meta ativa por vez. Definir outra encerra a atual e a barra recomeça do zero. Encerrar tira a barra da live.
- Valor de R$ 1,00 a R$ 1.000.000,00 e título de 2 a 80 caracteres.
- No modo de teste, a meta usa só presentes de teste.
Colocar no OBS
Uma fonte de navegador com o goal_overlay_url do criador (largura 1280, altura 720). Sem meta ativa, nada aparece na tela. Acrescente ?preview=1 para ver uma meta de exemplo que enche sozinha e posicionar a barra.
| Parâmetro | Padrão | O que faz |
|---|---|---|
preview=1 | — | Meta de exemplo que enche e esvazia sozinha. |
pos=top | top | Posição: top, center ou bottom. |
scale=1 | 1 | Tamanho da barra (0.4 a 3). |
valor=0 | mostra | Esconde os valores em reais e deixa só a porcentagem. |
ultimo=0 | mostra | Esconde a linha “Último: fulano enviou ...”. |
QR Code e cartaz
O público aponta o celular para o QR Code, escolhe o presente e paga por Pix, sem digitar endereço. Cada criador tem o QR Code do próprio link de presente em três formatos:
- Imagem (
qr_code_url, por exemplohttps://bday.fm/c/abc123xyz9/qr): um SVG que escala sem perder nitidez. No painel você baixa em SVG ou PNG. - Na tela da live (
qr_overlay_url): uma fonte de navegador do OBS que fixa o QR Code num canto, com o nome do criador e o link escrito. - Cartaz para imprimir (
poster_url): uma folha A4 com o QR Code grande, para eventos, lojas e vídeos.
Parâmetros da imagem
| Parâmetro | Padrão | O que faz |
|---|---|---|
margem=4 | 4 | Módulos brancos em volta (0 a 8). Os leitores precisam de margem: só reduza se o QR Code já estiver sobre um fundo claro. |
cor=1e1b4b | 000000 | Cor dos módulos, hexadecimal de 6 dígitos. Mantenha contraste alto com o fundo. |
fundo=ffffff | ffffff | Cor do fundo. |
tamanho=512 | — | Largura e altura em pixels (64 a 2048). Sem isso o SVG se adapta ao espaço. |
baixar=1 | — | Entrega como arquivo para baixar. |
Ajustes do QR Code na live
| Parâmetro | Padrão | O que faz |
|---|---|---|
pos=br | br | Canto: br (embaixo à direita), bl, tr, tl ou center. |
scale=1 | 1 | Tamanho (0.4 a 3). |
nome=0 | mostra | Esconde o nome do criador. |
link=0 | mostra | Esconde o endereço escrito embaixo do QR Code. |
Relatórios e extrato
Tudo o que aconteceu com os presentes, organizado no painel do parceiro e disponível em CSV. Cada tela tem o alternador de site (e, com mais de um, “Todos os sites”) e o de Real/Teste.
Relatórios
- Resumo do período: presentes, valor recebido, sua comissão, repasse dos criadores, parte do bday.fm, apoiadores, presente médio, maior presente e devoluções.
- Evolução por dia em gráfico, e os rankings de criadores, presentes, apoiadores e, com vários sites, sites.
- Período: 7, 30 ou 90 dias, este mês ou datas à sua escolha (até 366 dias), em horário de Brasília, e filtro por criador.
- Um presente devolvido fica no período em que foi pago e aparece à parte, fora dos totais.
- Os apoiadores são agrupados pelo nome que o fã informou (“Beto” e “beto” são a mesma pessoa), já que o fã não precisa ter conta.
Extrato
- Cada lançamento no seu saldo vindo dos sites: repasse do criador, comissão e devoluções, um por presente, com site, criador, apoiador e presente.
- A situação de cada crédito: em retenção (até a data de liberação), disponível ou anulado pela devolução.
- Totais do período (repasses, comissões, devoluções e líquido) e o saldo da conta, que é exatamente o da Carteira.
- Só dinheiro real: o modo de teste nunca gera lançamento.
Transações
A lista de presentes com o detalhe de cada um (a divisão do valor e o histórico de entrega do webhook), com exportação em CSV respeitando o site, o período e o criador escolhidos.
Para conciliar no seu próprio sistema, use a API: GET /api/v1/gifts?paid_since=....
Webhooks
A cada presente pago (e a cada devolução), o bday.fm faz um POST assinado para o seu servidor. É por aqui que você credita o criador.
Endereço
- Já vem preenchido no seu domínio (
https://seusite.com/bday/webhook): você não cria subdomínio, DNS nem certificado. Só coloca o receptor nessa rota. - Precisa ser
https, ter nome de domínio (não IP) e estar no seu domínio aprovado ou num subdomínio dele. - Não seguimos redirecionamentos. Se a rota redireciona (por exemplo, para uma tela de login), a entrega falha. Deixe a rota pública.
- Responda com qualquer 2xx em até 8 segundos. Faça o trabalho pesado depois de responder.
No painel, o botão Verificar instalação envia um aviso ping e mostra, em português, o que o seu servidor respondeu.
Cabeçalhos
| Cabeçalho | Valor |
|---|---|
Content-Type | application/json |
X-Bday-Signature | t=<timestamp unix>,v1=<assinatura hex> |
X-Bday-Event | gift.confirmed, gift.refunded ou ping |
X-Bday-Event-Id | Id do evento (o mesmo do campo id do corpo) |
X-Bday-Delivery-Attempt | Número da tentativa (1, 2, 3...) |
User-Agent | bday-webhooks/1.0 |
Eventos
| Evento | Quando | O que fazer |
|---|---|---|
gift.confirmed | O Pix foi aprovado. | Credite data.amounts.creator_cents ao criador data.recipient.ref. |
gift.refunded | O Pix foi devolvido depois de pago. | Desfaça o crédito do mesmo transaction_id. |
ping | Você clicou em “Verificar instalação”. | Responda 2xx. Não há nada a creditar. |
{
"id": "cmu9x2k3a0001abc",
"type": "gift.confirmed",
"livemode": true,
"created_at": "2026-09-20T15:04:05.000Z",
"data": {
"transaction_id": "cmu9x2k3a0000xyz",
"paid_at": "2026-09-20T15:04:05.000Z",
"giver": { "name": "Maria" },
"recipient": { "ref": "ID_DO_CRIADOR", "name": "Nome do criador" },
"message": "Adorei a live de hoje!",
"gift": {
"id": "gi_lua",
"name": "Lua de Presente",
"description": "Uma lua para iluminar o seu dia.",
"rarity": "lendario",
"category": "premium",
"emoji": "🌙",
"image_url": "https://bday.fm/api/img/presentes/gi_lua.webp",
"animation_url": "https://bday.fm/api/img/presentes/gi_lua.mp4"
},
"amounts": {
"currency": "BRL",
"gross_cents": 12000,
"creator_cents": 9600,
"partner_commission_cents": 600,
"platform_cents": 1800
}
}
}
O gift.refunded tem o mesmo formato, com "type": "gift.refunded" e o campo extra data.refunded_at. O ping traz apenas data.message.
Como conferir a assinatura
Sem conferir, qualquer pessoa que descubra o seu endereço poderia forjar “presentes” e você creditaria dinheiro que não existe. Faça sempre:
- Leia
X-Bday-Signaturee separet(timestamp) ev1(assinatura). - Use o corpo bruto, exatamente como chegou (antes de qualquer
JSON.parseou reformatação). - Calcule
HMAC-SHA256com o seu segredo (whsec_...) sobre o textot + "." + corpo, em hexadecimal. - Compare com
v1em tempo constante (timingSafeEqual,hash_equals,compare_digest). - Recuse se o
tfor mais velho que 5 minutos (protege contra reenvio de uma mensagem antiga).
const crypto = require('crypto');
// Registre esta rota ANTES de app.use(express.json()): a assinatura vale para o corpo exato.
app.post('/bday/webhook', express.raw({ type: '*/*' }), async (req, res) => {
const raw = req.body.toString('utf8');
const h = Object.fromEntries((req.get('X-Bday-Signature') || '').split(',').map(p => p.split('=')));
const esperado = crypto.createHmac('sha256', process.env.BDAY_WEBHOOK_SECRET)
.update(h.t + '.' + raw).digest('hex');
const valida = h.v1 && esperado.length === h.v1.length &&
crypto.timingSafeEqual(Buffer.from(esperado), Buffer.from(h.v1)) &&
Math.abs(Date.now() / 1000 - Number(h.t)) < 300;
if (!valida) return res.sendStatus(401);
const ev = JSON.parse(raw);
if (ev.type !== 'ping') await tratarEvento(ev);
res.sendStatus(200);
});
async function tratarEvento(ev) {
// ev.id: guarde para não processar duas vezes.
// ev.livemode === false: presente de TESTE, não credite saldo real.
const criadorId = ev.data.recipient.ref;
const centavos = ev.data.amounts.creator_cents;
const sinal = ev.type === 'gift.refunded' ? -1 : 1;
// TODO: some (sinal * centavos) ao saldo do criador criadorId.
}// app/bday/webhook/route.ts
import crypto from 'crypto';
export async function POST(req: Request) {
const raw = await req.text();
const h = Object.fromEntries((req.headers.get('x-bday-signature') || '').split(',').map(p => p.split('=')));
const esperado = crypto.createHmac('sha256', process.env.BDAY_WEBHOOK_SECRET!)
.update(h.t + '.' + raw).digest('hex');
const valida = h.v1 && esperado.length === h.v1.length &&
crypto.timingSafeEqual(Buffer.from(esperado), Buffer.from(h.v1)) &&
Math.abs(Date.now() / 1000 - Number(h.t)) < 300;
if (!valida) return new Response(null, { status: 401 });
const ev = JSON.parse(raw);
if (ev.type !== 'ping') await tratarEvento(ev);
return new Response(null, { status: 200 });
}
async function tratarEvento(ev: any) {
// ev.id: guarde para não processar duas vezes.
// ev.livemode === false: presente de TESTE, não credite saldo real.
const criadorId = ev.data.recipient.ref;
const centavos = ev.data.amounts.creator_cents;
const sinal = ev.type === 'gift.refunded' ? -1 : 1;
// TODO: some (sinal * centavos) ao saldo do criador criadorId.
}<?php
$raw = file_get_contents('php://input');
parse_str(str_replace(',', '&', $_SERVER['HTTP_X_BDAY_SIGNATURE'] ?? ''), $h);
$esperado = hash_hmac('sha256', ($h['t'] ?? '') . '.' . $raw, getenv('BDAY_WEBHOOK_SECRET'));
if (!isset($h['v1']) || !hash_equals($esperado, $h['v1']) || abs(time() - (int)($h['t'] ?? 0)) > 300) {
http_response_code(401); exit;
}
$ev = json_decode($raw, true);
if ($ev['type'] !== 'ping') {
// $ev['id']: guarde para não processar duas vezes.
// $ev['livemode'] === false: presente de TESTE, não credite saldo real.
$criadorId = $ev['data']['recipient']['ref'];
$centavos = $ev['data']['amounts']['creator_cents'];
$sinal = $ev['type'] === 'gift.refunded' ? -1 : 1;
// TODO: some ($sinal * $centavos) ao saldo do criador $criadorId.
}
http_response_code(200);import hmac, hashlib, os, time
from flask import Flask, request, abort
app = Flask(__name__)
def assinatura_valida(raw: bytes, cabecalho: str, segredo: str) -> bool:
try:
partes = dict(p.split("=", 1) for p in cabecalho.split(","))
ts = int(partes["t"])
except (ValueError, KeyError):
return False
esperado = hmac.new(segredo.encode(), str(ts).encode() + b"." + raw, hashlib.sha256).hexdigest()
return abs(time.time() - ts) <= 300 and hmac.compare_digest(esperado, partes.get("v1", ""))
@app.post("/bday/webhook")
def bday_webhook():
raw = request.get_data() # o corpo exato, sem reformatar
if not assinatura_valida(raw, request.headers.get("X-Bday-Signature", ""), os.environ["BDAY_WEBHOOK_SECRET"]):
abort(401)
ev = request.get_json()
if ev["type"] != "ping":
# ev["id"]: guarde para não processar duas vezes.
# ev["livemode"] is False: presente de TESTE, não credite saldo real.
criador_id = ev["data"]["recipient"]["ref"]
centavos = ev["data"]["amounts"]["creator_cents"]
sinal = -1 if ev["type"] == "gift.refunded" else 1
# TODO: some (sinal * centavos) ao saldo do criador criador_id.
return "", 200Vetor de teste
Para conferir a sua implementação sem esperar um presente, use estes valores. O resultado do seu cálculo precisa ser idêntico:
segredo whsec_exemplo_123
t 1700000000
corpo {"id":"evt_exemplo","type":"ping"}
v1 4548b70b240017ffc45598e01898a6e4f00a9d792c0102a2fb6c49ccf022e386
(A verificação de horário, que recusa mensagens com mais de 5 minutos, falhará para esse t antigo: teste só o cálculo do HMAC.)
Reentregas e idempotência
- Se o seu servidor não responder 2xx, o bday.fm tenta de novo com espera crescente: 1 min, 5 min, 30 min, 2 h, 6 h, 12 h e 24 h, num total de 8 tentativas (cerca de 2 dias). Depois disso o evento fica como “Falhou” e você pode reenviá-lo pelo painel (Transações → abrir a transação → Reenviar webhook).
- O mesmo evento pode chegar mais de uma vez. Guarde o
iddo evento (ou o partransaction_id+type) e ignore o que já processou. - Cada presente gera no máximo um
gift.confirmede umgift.refunded. - Se o seu servidor ficou fora do ar, concilie pela API:
GET /api/v1/gifts?paid_since=....
API de servidor (v1)
Para o seu servidor cadastrar criadores, conciliar presentes e (no modo de teste) simular pagamentos. Endereço base: https://bday.fm. Especificação completa: openapi.json.
Autenticação
Crie uma chave secreta no painel (aba API). Ela aparece uma única vez: copie na hora. Envie no cabeçalho:
Authorization: Bearer sk_live_SUA_CHAVE
sk_live_...vê e altera dados reais.sk_test_...só enxerga o modo de teste.- Nunca coloque a chave secreta no navegador, em app mobile ou em repositório público. Se vazar, revogue no painel e crie outra.
- Você pode ter até 5 chaves ativas por modo (útil para trocar sem parada) e revogar cada uma sozinha.
/api/v1/meConfere a chave e devolve as regras vigentes. É o melhor primeiro teste.
curl https://bday.fm/api/v1/me -H "Authorization: Bearer sk_test_SUA_CHAVE"
{
"site_name": "Meu Site",
"livemode": false,
"split": { "creator_percent": 80, "partner_percent": 5, "platform_percent": 15 },
"hold_days": 7
}
/api/v1/catalogOs presentes disponíveis, com arte, animação, descrição, raridade e preço. Só entram presentes virtuais e pagos.
{
"object": "list",
"data": [
{
"id": "gi_lua", "name": "Lua de Presente", "description": "...", "rarity": "lendario",
"category": "premium", "emoji": "🌙", "price_cents": 12000, "currency": "BRL",
"image_url": "https://bday.fm/api/img/presentes/gi_lua.webp",
"animation_url": "https://bday.fm/api/img/presentes/gi_lua.mp4"
}
],
"has_more": false
}
/api/v1/creators/{ref}Cadastra ou atualiza um criador (idempotente). {ref} é o id dele no seu sistema: letras, números e . _ : @ -, até 80 caracteres. Corpo: name (obrigatório, até 80) e avatar_url (opcional, https).
curl -X PUT https://bday.fm/api/v1/creators/lia_01 \
-H "Authorization: Bearer sk_test_SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{"name": "Lia", "avatar_url": "https://cdn.exemplo.com/lia.jpg"}'
{
"ref": "lia_01",
"name": "Lia",
"avatar_url": "https://cdn.exemplo.com/lia.jpg",
"livemode": false,
"gift_page_url": "https://bday.fm/c/k3j9x2m8ab",
"overlay_url": "https://bday.fm/overlay/ov_Xk3...",
"goal_overlay_url": "https://bday.fm/overlay/ov_Xk3.../meta",
"qr_overlay_url": "https://bday.fm/overlay/ov_Xk3.../qr",
"qr_code_url": "https://bday.fm/c/k3j9x2m8ab/qr",
"poster_url": "https://bday.fm/c/k3j9x2m8ab/cartaz",
"created_at": "2026-09-20T15:00:00.000Z"
}
/api/v1/creators/{ref}Consulta um criador (mesmo formato acima). 404 se não existir naquele modo.
/api/v1/creatorsLista os criadores, dos mais novos para os mais antigos. Parâmetros: limit (1 a 100, padrão 25) e starting_after (o ref do último criador da página anterior). A resposta tem data e has_more.
/api/v1/creators/{ref}/overlay/rotateGera um novo overlay_url (e, junto, os de meta e QR Code da live) e desativa o anterior na hora. Devolve o criador.
/api/v1/creators/{ref}/goalDefine a meta do criador. Se já havia uma ativa, ela é encerrada e a barra recomeça do zero: só conta o que for pago depois. Corpo: title (2 a 80 caracteres) e target_cents (inteiro, de 100 a 100000000).
curl -X PUT https://bday.fm/api/v1/creators/ID_DO_CRIADOR/goal \
-H "Authorization: Bearer sk_live_SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{"title": "Novo microfone", "target_cents": 100000}'
{
"id": "cmu9x2k3a0007abc",
"title": "Novo microfone",
"target_cents": 100000,
"current_cents": 35000,
"remaining_cents": 65000,
"percent": 35,
"reached": false,
"supporters": 4,
"started_at": "2026-09-21T18:00:00.000Z",
"reached_at": null,
"last": { "giver": "Maria", "gift": "Lua de Presente", "amount_cents": 12000, "paid_at": "2026-09-21T18:40:00.000Z" },
"widget_url": "https://bday.fm/overlay/ov_Xk3.../meta"
}
/api/v1/creators/{ref}/goalDevolve a meta ativa com o progresso de agora (mesmo formato acima), ou 404 se o criador não tem meta. É o que você chama para mostrar a barra também no seu site.
/api/v1/creators/{ref}/goalEncerra a meta ativa: a barra some da live. 404 se não havia meta.
/api/v1/giftsLista presentes para conciliar, do mais novo para o mais antigo.
| Parâmetro | Descrição |
|---|---|
status | paid, refunded, pending, expired ou all. Padrão: pagos e devolvidos. |
creator_ref | Só os presentes de um criador. |
paid_since | Só pagos a partir desse instante (ISO 8601). Ideal para “o que perdi desde a última conferência?”. |
limit, starting_after | Paginação: até 100 por página; starting_after é o id do último presente da página anterior. |
curl "https://bday.fm/api/v1/gifts?status=paid&paid_since=2026-09-20T00:00:00Z&limit=50" \
-H "Authorization: Bearer sk_live_SUA_CHAVE"
/api/v1/gifts/{id}Consulta um presente. O id é o mesmo transaction_id do webhook. Formato em Objeto presente.
/api/v1/gifts/{id}/simulateSó com sk_test_. Simula o que o Pix faria: {"event": "paid"} paga o presente de teste e {"event": "refunded"} o devolve. Em ambos os casos o webhook assinado é enviado ao seu receptor.
curl -X POST https://bday.fm/api/v1/gifts/ID_DO_PRESENTE/simulate \
-H "Authorization: Bearer sk_test_SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{"event": "paid"}'
Objeto presente
É o mesmo formato na API (GET /api/v1/gifts) e dentro de data nos webhooks (onde id aparece como transaction_id).
| Campo | Descrição |
|---|---|
id | Id da transação. Único e estável. |
status | pending (Pix gerado, aguardando), paid, expired (o Pix venceu em 30 min) ou refunded. |
livemode | false = presente do modo de teste. |
created_at, paid_at | Datas ISO 8601 (UTC). paid_at é null antes do pagamento. |
giver.name | Como o fã quis aparecer. Texto de terceiro: escape. |
recipient.ref, recipient.name | O criador, do jeito que o seu site informou. |
message | Recado do fã (até 300 caracteres) ou null. Texto de terceiro: escape. |
gift | id, name, description, rarity (comum, raro, epico ou lendario), category, emoji, image_url e animation_url (vídeo curto, sem áudio). |
amounts.gross_cents | O que o fã pagou, em centavos. |
amounts.creator_cents | Repasse do criador: é o que você credita no seu site. |
amounts.partner_commission_cents | A sua comissão (entra no seu saldo bday.fm). |
amounts.platform_cents | A parte do bday.fm. A soma das três partes é sempre igual a gross_cents. |
Valores são sempre inteiros em centavos (nunca decimais), em BRL.
Erros e limites
Toda falha da API v1 tem o mesmo formato:
{ "error": { "code": "invalid_request", "message": "avatar_url precisa ser um endereço https válido (até 300 caracteres)." } }
| HTTP | code | Quando |
|---|---|---|
| 400 | invalid_request | Corpo ou parâmetro inválido. A message diz qual. |
| 401 | unauthorized | Sem chave, chave inválida, revogada ou de outro tipo (a chave pública pk_ não serve aqui). |
| 403 | partner_not_active | A parceria está suspensa. |
| 403 | test_mode_only | Simulação usada com chave real. |
| 404 | not_found | Não existe naquele modo ou não é seu. Presente de teste não é visto pela chave real, e vice-versa. |
| 409 | invalid_state | Ação incompatível com o estado atual (por exemplo, devolver um presente ainda não pago). |
| 429 | rate_limited | Passou de 300 requisições por minuto por chave. Espere e tente de novo (há Retry-After). |
Segurança
- Confira a assinatura de todo webhook e recuse mensagens com mais de 5 minutos.
- Credite só pelo webhook (ou pela API), nunca pelo
onSuccessdo navegador. - Segredos em variáveis de ambiente:
whsec_...esk_...nunca vão no código nem no navegador. Se um vazar, gere outro no painel. - Seja idempotente: guarde o
iddo evento e ignore repetidos. - Escape nome do fã e recado antes de exibir.
- Trate o
overlay_urlcomo segredo e troque se vazar. - Não guardamos nem enviamos o e-mail do fã ao parceiro. O que você recebe é só nome, recado e presente.
Ir para produção
- O receptor confere a assinatura e responde 2xx (o botão Verificar instalação do painel passa).
- Você já testou um presente de teste ponta a ponta e viu o
gift.confirmede ogift.refundedchegarem. - O receptor ignora eventos repetidos e trata
livemode: falsesem creditar saldo real. - O snippet do botão usa a chave real (
pk_live_...). - A sua chave secreta real (
sk_live_...) está só no servidor. - O criador colou o
overlay_urlno OBS e viu o alerta de exemplo (?preview=1). - Sua conta bday.fm tem a identidade verificada e a chave Pix cadastrada, para poder sacar.
Perguntas frequentes
Preciso de CNPJ?
Não. Basta ter uma conta no bday.fm, que é onde o seu saldo é recebido e sacado por Pix.
O fã precisa ter conta no bday.fm?
Não. Ele informa o nome como quer aparecer e um e-mail (exigido pelo Pix, nunca repassado a você) e paga.
O criador precisa ter conta no bday.fm?
Não. O criador só existe no seu site: o valor dele cai no seu saldo e você o credita lá.
Posso escolher quais presentes aparecem?
Hoje o modal mostra todos os presentes virtuais pagos do catálogo, e o catálogo é o mesmo para todos os parceiros.
Posso mudar a minha comissão?
Não: ela é definida pelo bday.fm e a chamada GET /api/v1/me mostra o valor vigente.
O que acontece se o fã pedir a devolução do Pix?
Você recebe o gift.refunded e o valor sai do seu saldo. Desfaça o crédito do criador no seu site (por isso a retenção de alguns dias antes do saque).
O overlay funciona com Streamlabs, Meld e outros?
Ele é uma página web comum, então qualquer programa de live que tenha “fonte de navegador” consegue exibi-lo. O passo a passo acima é o do OBS Studio.
Posso ter mais de um site na mesma conta?
Sim, até 10 pedidos ao mesmo tempo. Cada site é uma parceria à parte, com chaves, criadores e webhook próprios, e o saldo é um só: o da conta. Peça em Ajustes → Parcerias e lives → Adicionar outro site.
Como mostro a meta e o QR Code na minha live?
No painel, em Criadores e live, clique em Preparar live no criador. Lá estão os endereços das três fontes do OBS (alerta, meta e QR Code), com “ver exemplo”, e a definição da meta. Veja Meta em tempo real e QR Code e cartaz.
Onde vejo o extrato do dinheiro que entrou?
No painel, na aba Extrato (por site ou de todos os sites juntos), com cada repasse, comissão e devolução ligados ao presente. O saldo é o mesmo da sua Carteira. Veja Relatórios e extrato.
Quantos criadores posso ter?
Não há limite de criadores.
Onde vejo tudo o que aconteceu?
No painel, em Transações: lista, detalhe de cada presente, histórico de entrega do webhook e exportação em CSV. Você também recebe um e-mail a cada presente confirmado.
Preciso de ajuda com a integração.
Escreva para contato@bday.fm contando o endereço do seu site e, se possível, o que apareceu no botão Verificar instalação.
Novidades
21 de setembro de 2026
- Ajustes no menu da conta: central com o pedido de parceria, os sites da conta e o acesso ao painel e ao extrato.
- Vários sites por conta: cada site é uma parceria à parte, com o saldo da conta em comum.
- Meta em tempo real para a live, com a API
/api/v1/creators/{ref}/goal. - QR Code do link de presente (imagem SVG, fonte do OBS e cartaz para imprimir).
- Relatórios e extrato organizados por período, criador, presente, apoiador e site.
- O objeto do criador na API ganhou os campos
goal_overlay_url,qr_overlay_url,qr_code_urleposter_url(mudança compatível).
20 de setembro de 2026
- Modo de teste: chaves
pk_test_esk_test_, simulação de pagamento e estorno, sem cobrança e sem mexer em saldo. - API de servidor v1 com chave secreta:
/me,/catalog,/creators,/giftse/simulate, mais a especificação OpenAPI. - Criadores, link de presente e overlay de live para OBS.
- Webhooks: novo campo
livemodeno corpo. Mudança compatível: quem ignora campos desconhecidos não precisa mexer em nada.
19 de setembro de 2026
- Lançamento do programa de parceiros: modal de presentes, webhooks assinados e painel do parceiro.
