Guias
Pagamentos via API
Se você já tem sua própria interface — app, dashboard, marketplace, carteira digital, plataforma P2P, casa de apostas, qualquer coisa — e só precisa receber pagamentos e enviar saques via PIX sem usar o checkout hospedado da iHubGames, este guia é pra você.
Em uma frase: seu usuário paga via PIX (cash-in), você acompanha o saldo, e quando ele saca você manda PIX de volta (cash-out). Os webhooks fecham o ciclo, notificando seu sistema quando o pagamento chega e quando o saque é confirmado.
É o modelo conhecido como checkout transparente: o usuário final nunca vê tela da iHubGames — todo o fluxo acontece dentro do seu produto, e a gente só processa o dinheiro nos bastidores. Este guia te leva do zero a um fluxo de produção sem passar pelas partes da API pensadas pra catálogo e cobrança recorrente.
Quando esse modelo se aplica
"Pagamentos via API" cobre qualquer caso onde você controla a UI de pagamento e só precisa de movimentação financeira:
- Marketplaces — comprador paga, parte vai pro vendedor, parte fica retida.
- Carteiras / wallets — usuário deposita saldo, gasta dentro do app, saca quando quer.
- Plataformas P2P — repasse direto entre usuários, com a plataforma intermediando.
- iGaming / bet — depósito do jogador, pagamento de prêmio.
- Apps de freelancer / gig economy — pagamento ao prestador após conclusão do serviço.
- Qualquer SaaS que cobra via PIX sem checkout pronto — você emite a cobrança no seu sistema e usa a API só pra gerar o BR Code.
Se em algum momento você se perguntou "preciso só de uma API que recebe PIX e manda PIX, sem perder tempo com catálogo de produto" — você está no guia certo.
O que você precisa em produção
Cinco etapas cobrem 100% do fluxo:
| # | Etapa | Como você faz |
|---|---|---|
| 1 | Receber pagamento de entrada | POST /transactions/v2/purchase com paymentMethod: "PIX" |
| 2 | Confirmar pagamento | Webhook cashin.paid (Payload v2) ou status: "APPROVED" em Payload v1 |
| 3 | Enviar pagamento de saída | POST /withdraws/cash-out com a chave PIX do destinatário |
| 4 | Confirmar saque | Webhook cashout.success (v2) ou status: "WITHDRAW_APPROVED" (v1) |
| 5 | Acompanhar caixa | GET /accounts/balance para conciliação |
É só isso. Não há fluxo de catálogo, assinatura, cupom nem checkout hospedado — sua plataforma já tem o cadastro do usuário, você só precisa que o dinheiro entre e saia.
Fluxo de cash-in
1. Seu usuário escolhe um valor pra pagar na sua plataforma.
2. Você cria a transação via API:
curl -X POST "https://api.ihubplay.com/transactions/v2/purchase" \
-H "Authorization: Basic $(echo -n 'secret:SUA_SECRET_KEY' | base64)" \
-H "Content-Type: application/json" \
-d '{
"name": "João Silva",
"email": "joao@exemplo.com",
"cpf": "12345678901",
"phone": "9876543210",
"amount": 5000,
"description": "Pagamento - pedido 1234",
"responsibleDocument": "12345678901",
"responsibleExternalId": "user-1234",
"externalId": "pedido-9876",
"paymentMethod": "PIX",
"restrictPayerDocument": true
}'
amount: 5000= R$ 50,00. Todos os valores em centavos.
3. Você recebe um pixCode (BR Code copia-e-cola). Mostre como QR Code ou texto pro usuário dentro do seu app.
4. Quando o usuário pagar, você recebe um webhook:
{
"event": "cashin.paid",
"environment": "LIVE",
"payload": {
"transaction_id": "17615714245971918718644287",
"external_id": "pedido-9876",
"amount": 5000,
"end_to_end_id": "E18236120202610271324s05499b347c",
"payer": {
"name": "João Silva",
"document": "12345678901",
"ispb": "18236120",
"institution": "NU PAGAMENTOS - IP"
},
"receiver": {
"name": "SUA EMPRESA LTDA",
"document": "12345678000199",
"ispb": "27084098",
"institution": "TRANSFEERA IP S.A."
},
"pix_key": null,
"source_type": "API",
"invoice_id": null,
"offer_id": null,
"product_id": null,
"quick_link_id": null
}
}
5. Seu handler valida assinatura, credita o usuário no seu sistema, retorna 200 OK. Pronto.
💡
restrictPayerDocument: truetrava a transação ao CPF que você passou emcpf. Se outra pessoa tentar pagar, o banco rejeita. É a defesa mais forte contra fraude de pagamento por terceiros — terceiro paga, depois contesta, o dinheiro volta, mas o seu usuário já ficou com o crédito. Recomendado sempre que o valor for relevante (especialmente em marketplaces, iGaming e P2P).
Detalhes adicionais: Criar transação, Buscar transação, Estornar transação.
Cash-in com cartão de crédito
Cartão usa o mesmo endpoint de pagamento (POST /transactions/v2/purchase), mudando paymentMethod pra CREDIT_CARD. Por segurança (PCI) existem dois modelos — escolha conforme o seu caso:
- Modelo A — Token (checkout no navegador): pro lojista comum, sem PCI. O número é tokenizado no navegador com a nossa biblioteca iHubGames.js (nunca toca o seu servidor) e você manda só o
token. É o fluxo dos passos 1–5 abaixo. - Modelo B — PAN cru (sub-adquirente PCI): pra quem já tem o número do cartão no servidor (sub-adquirente PCI compliant, cascata server-to-server). Você manda o
numberdireto — ver Modelo B no fim.
O 3D Secure, quando o emissor exige, precisa de um desafio no navegador — vale pros dois modelos.
Modelo A — Token (passo a passo):
1. Pegue a config de tokenização (a tokenizationKey é pública, pode ir pro front):
curl "https://api.ihubplay.com/transactions/card-config" \
-H "Authorization: Basic $(echo -n 'secret:SUA_SECRET_KEY' | base64)"
# → { "available": true, "tokenizationKey": "pgk_live_...",
# "allowsInstallments": true }
Se available: false, a conta ainda não tem cartão habilitado (só PIX).
2. Tokenize o cartão no navegador com a iHubGames.js (o número do cartão nunca toca o seu servidor). A biblioteca fica em https://portal.ihubplay.com/sdk/hubplay.js:
<script src="https://portal.ihubplay.com/sdk/hubplay.js"></script>
const card = iHubGames.card({ tokenizationKey }); // do passo 1
await card.mount("#card-element"); // monta o campo de cartão
const { token } = await card.tokenize({ name: "João Silva" });
// token = string opaca → mande pro SEU servidor
3. No seu servidor, crie a transação com o token:
curl -X POST "https://api.ihubplay.com/transactions/v2/purchase" \
-H "Authorization: Basic $(echo -n 'secret:SUA_SECRET_KEY' | base64)" \
-H "Content-Type: application/json" \
-d '{
"name": "João Silva",
"email": "joao@exemplo.com",
"cpf": "12345678901",
"amount": 5000,
"description": "Pedido 1234",
"externalId": "pedido-9876",
"paymentMethod": "CREDIT_CARD",
"creditCard": {
"token": "tkn_9f2c8a...",
"holder": "JOAO SILVA",
"installments": 1,
"brand": "mastercard",
"last4": "3086"
}
}'
4. Trate a resposta:
- Aprovado direto (cartão sem 3DS):
{ "status": "APPROVED", "transactionId": "1785...", "amount": 5000 } - Exige 3D Secure — vem com
requiresAction+clientSecret:
{ "status": "PENDING", "requiresAction": true,
"clientSecret": "pi_..._secret_...", "transactionId": "1785..." }
Devolva o clientSecret pro navegador e apresente o desafio com a mesma instância da iHubGames.js:
await card.confirmAction(clientSecret);
// A iHubGames.js abre o desafio de autenticação automaticamente.
// Sem erro = autenticado; aí é só aguardar a confirmação (passo 5).
5. Finalização. Depois do 3DS (ou direto, se não teve), a venda é confirmada pelo webhook cashin.paid (igual PIX) — é ele que marca APPROVED e credita o saldo. Dá pra fazer polling em GET /transactions/:id também.
Modelo B — PAN cru (sub-adquirente PCI)
Se você já tem o número do cartão no servidor (sub-adquirente PCI, cascata Checkout → sub-adquirente → você → iHubGames), pule a iHubGames.js e mande o PAN direto no mesmo endpoint — sem token:
curl -X POST "https://api.ihubplay.com/transactions/v2/purchase" \
-H "Authorization: Basic $(echo -n 'secret:SUA_SECRET_KEY' | base64)" \
-H "Content-Type: application/json" \
-d '{
"name": "João Silva",
"email": "joao@exemplo.com",
"cpf": "12345678901",
"amount": 5000,
"description": "Pedido 1234",
"externalId": "pedido-9876",
"paymentMethod": "CREDIT_CARD",
"creditCard": {
"number": "5155901222280001",
"holder": "JOAO SILVA",
"expMonth": "12",
"expYear": "2030",
"cvv": "123",
"installments": 2
}
}'
O backend deriva last4, bin e brand do próprio número — não precisa mandá-los.
3D Secure no Modelo B — pode exigir ou não
A resposta do Modelo B é idêntica à do Modelo A, e o cartão pode ou não exigir 3D Secure — quem decide é o emissor do cartão, não você:
- Sem 3DS → a resposta vem
{ "status": "APPROVED", ... }na hora. Fim. (Grande parte dos cartões, especialmente valores baixos e MIT/recorrência elegíveis, passam direto.) - Com 3DS → a resposta vem
{ "status": "PENDING", "requiresAction": true, "clientSecret": "..." }. O portador precisa autenticar num navegador — não há como concluir 3DS 100% server-side (é regra do próprio 3DS/SCA). Você apresenta o desafio com a iHubGames.js usando oclientSecret:
<script src="https://portal.ihubplay.com/sdk/hubplay.js"></script>
const card = iHubGames.card({ tokenizationKey }); // do card-config
await card.confirmAction(clientSecret); // abre o desafio 3DS
// concluído → o webhook cashin.paid marca APPROVED
Onde apresentar o 3DS na cascata? No seu fluxo
Checkout → sub-adquirente → você, o desafio precisa acontecer onde existe o navegador do portador (normalmente o "Checkout" do topo). Se o seu fluxo for 100% server-to-server sem navegador (ex.: MOTO), transações que o emissor exigir 3DS ficamPENDINGe não concluem; só passam as que se qualificam pra isenção (valor baixo, MIT). Por isso, quando há navegador no fluxo, o Modelo A (tokenizar no navegador) é mais simples — já resolve tokenização e 3DS no mesmo lugar.
⚠️ Requisito de PCI (Modelo B): você precisa ser PCI DSS compliant — o número do cartão trafega pelo seu servidor. O PAN é tokenizado no nosso backend antes de qualquer cobrança (o número não é armazenado). Recomendamos o Modelo A (token) sempre que houver um navegador no fluxo; use o Modelo B só quando a origem já for PCI e server-to-server.
last4/brand: opcionais nos dois modelos. No Modelo A a iHubGames.js já devolve; no Modelo B o backend deriva do número.
Parcelamento: informe
installments(2..N). SeallowsInstallments: falsena config, envie sempre1— a API rejeita parcelado. O mínimo por parcela é validado pela operadora.
Descritor na fatura: aparece como
IHUBGAMES* NOME DO LOJISTA— a iHubGames é o merchant of record; o nome do lojista vai no sufixo.
Fluxo de cash-out
1. Seu usuário (ou seu sistema) pede um envio de PIX informando a chave do destinatário.
2. Você valida internamente (saldo disponível, KYC, antifraude) e chama a API:
curl -X POST "https://api.ihubplay.com/withdraws/cash-out" \
-H "Authorization: Basic $(echo -n 'secret:SUA_SECRET_KEY' | base64)" \
-H "Content-Type: application/json" \
-d '{
"amount": 10000,
"pixKey": "joao@exemplo.com",
"pixType": "EMAIL",
"document": "12345678901",
"restrictReceiverDocument": true,
"externalId": "envio-4321"
}'
amount: 10000= R$ 100,00.restrictReceiverDocument: trueexige que o CPF retornado pelo DICT bata com o documento informado. Recomendado sempre que você souber pra quem está pagando — protege contra reatribuição de chave PIX (a chave foi excluída e usada por outra pessoa).
3. A resposta é assíncrona — você recebe WITHDRAW_REQUEST e o resultado final chega por webhook em segundos a alguns minutos:
{
"event": "cashout.success",
"environment": "LIVE",
"payload": {
"withdrawal_id": "17615714245971918718644287",
"external_id": "envio-4321",
"amount": 10000,
"end_to_end_id": "E18236120202610271324s05499b347c",
"receiver": {
"name": "Maria Souza",
"document": "98765432100",
"ispb": "60701190",
"institution": "ITAÚ UNIBANCO S.A."
},
"payer": {
"name": "SUA EMPRESA LTDA",
"document": "12345678000199",
"ispb": "27084098",
"institution": "TRANSFEERA IP S.A."
}
}
}
4. Estados possíveis para o saque:
| Status v2 | Status v1 | O que fazer |
|---|---|---|
cashout.success | WITHDRAW_APPROVED | Confirme no seu sistema. Fundos saíram do seu saldo. |
cashout.failed | WITHDRAW_REJECTED / WITHDRAW_ERROR | Fundos voltam ao seu saldo. Notifique o destinatário. |
cashout.returned | WITHDRAW_RETURNED | Foi aprovado e depois devolvido. Fundos voltam. Investigue antes de tentar de novo. |
⚠️ Nunca faça retry automático em estado intermediário (
WITHDRAW_REQUEST/WITHDRAW_PROCESSING). Aguarde o webhook final. Fazer retry sem confirmação é a forma mais comum de empresas pagarem o mesmo destinatário duas vezes por engano.
Detalhes adicionais: Saque por chave PIX, Saque por QR Code, Buscar saque.
Saque em cripto (USDT · TRON)
Além do PIX, dá pra sacar parte do seu saldo em USDT na rede TRON (TRX).
É um fluxo manual, operado pela equipe iHubGames — não é self-service por API nem pelo painel. Você combina o saque com o seu contato comercial; a equipe executa e registra o envio.
Como funciona:
- Conversão BRL → USDT. O valor em reais do seu saldo é convertido para USDT na cotação do momento do envio, mais uma taxa combinada.
- Rede TRON (TRX) apenas, por enquanto. A carteira de destino tem que ser um endereço TRON válido (começa com
T). - Valor mínimo por operação (hoje a partir de R$ 100.000 — confirme o piso atual com o seu contato).
- Débito do saldo. Ao iniciar, o valor + a taxa são debitados e travados no seu saldo em BRL. Se o envio não acontecer, o valor é estornado.
Depois de concluído, o saque aparece no seu extrato como um saque do tipo cripto, com todos os dados de conferência: carteira de destino, rede, cotação aplicada, taxa, USDT enviado, data/hora e o hash da transação — com link direto pro Tronscan pra você auditar o envio on-chain.
Segurança operacional
Não negocie estes itens em produção:
- IP allowlist para a chave de cash-out. Chaves com
createWithdrawprecisam estar travadas a IPs específicos no dashboard. Sem allowlist, uma chave vazada vira saque pra carteira de outra pessoa em minutos. Veja Autenticação e chaves para detalhes. - Separe chaves de API por contexto. Uma chave
viewBalancepro dashboard interno, uma chavecreateTransactionpra entrada, uma chavecreateWithdrawpra saída (com allowlist apertado). Vazamento de uma não compromete as outras. - Webhooks idempotentes. Persista
transaction_idewithdrawal_idno seu banco e ignore reentregas. A iHubGames reentrega entregas que falharam com backoff exponencial por até 24h. - Verifique a assinatura HMAC. URLs de webhook vazam — sem validar a assinatura, qualquer um que descobrir sua URL pode forjar um
cashin.paide levar crédito de graça. Veja Verificação de assinatura. - Persista o
x-trace-id. Toda resposta da API e todo webhook carregam umx-trace-idno header. Guarde junto com sua linha de transação — quando algo der estranho, ele é o caminho mais rápido pra investigação. Veja Trace ID e debug.
O que você NÃO precisa
A iHubGames expõe vários módulos que não fazem sentido pra esse modelo e que você pode ignorar com tranquilidade:
- Clientes — você já tem o usuário cadastrado na sua plataforma. Não precisa criar um
Customerna iHubGames pra cada pagamento. - Produtos / Ofertas — não há catálogo. O que está sendo "vendido" (crédito, serviço, ticket) é gerenciado no seu sistema.
- Cupons — cupons só funcionam dentro do checkout hospedado da iHubGames, que esse modelo não usa.
- Assinaturas / Invoices recorrentes — se você precisa de cobrança recorrente, dá pra gerar uma nova transação no seu próprio agendador. Os módulos de Subscription/Invoice existem pra quem usa o checkout pronto.
- Checkout hospedado (QuickLinks / Offers) — você usa fluxo dentro do seu próprio app, não link compartilhável.
Se em algum momento você quiser adicionar catálogo, checkout hospedado ou assinatura recorrente em cima desse fluxo, veja o guia Catálogo e Assinaturas.