NXGate SDK para Elixir
SDK oficial da NXGATE para integração com a API PIX em aplicações Elixir.
Funcionalidades
- Geração de cobranças PIX (cash-in) com QR Code
- Saques PIX (cash-out)
- Consulta de saldo e transações
- Gerenciamento automático de token OAuth2 via GenServer
- Assinatura HMAC-SHA256 automática (quando configurado)
- Parser de webhooks para eventos PIX
- Retry automático com backoff em erros 503
-
Zero dependências HTTP externas (usa
:httpcda stdlib Erlang)
Requisitos
- Elixir ~> 1.14
- Erlang/OTP ~> 25
Instalação
Adicione nxgate às suas dependências no mix.exs:
def deps do
[
{:nxgate, "~> 0.1.0"}
]
endConfiguração
Início Rápido
# Iniciar o client (geralmente no seu application supervisor)
{:ok, client} = NXGate.start_link(
client_id: "nxgate_xxx",
client_secret: "secret",
hmac_secret: "opcional" # opcional - ativa assinatura HMAC
)Uso com Supervisor
Adicione o client ao seu supervisor para gerenciamento automático do ciclo de vida:
defmodule MyApp.Application do
use Application
@impl true
def start(_type, _args) do
children = [
{NXGate,
client_id: System.fetch_env!("NXGATE_CLIENT_ID"),
client_secret: System.fetch_env!("NXGATE_CLIENT_SECRET"),
hmac_secret: System.get_env("NXGATE_HMAC_SECRET"),
name: :nxgate}
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
endOpções de Configuração
| Opção | Tipo | Obrigatório | Padrão | Descrição |
|---|---|---|---|---|
client_id | string | Sim | - | ID do client OAuth2 |
client_secret | string | Sim | - | Secret do client OAuth2 |
hmac_secret | string | Não | nil | Secret para assinatura HMAC-SHA256 |
base_url | string | Não | https://api.nxgate.com.br | URL base da API |
timeout | integer | Não | 15000 | Timeout em milissegundos |
max_retries | integer | Não | 2 | Máximo de retentativas em erro 503 |
Uso
Gerar Cobrança PIX (Cash-in)
Gera uma cobrança PIX e retorna o QR Code para pagamento:
{:ok, charge} = NXGate.pix_generate(client, %{
valor: 100.00,
nome_pagador: "João da Silva",
documento_pagador: "12345678901",
webhook: "https://meusite.com/webhook",
descricao: "Pagamento do pedido #123"
})
# Resposta:
# %{
# "status" => "success",
# "message" => "...",
# "paymentCode" => "00020126...",
# "idTransaction" => "abc123",
# "paymentCodeBase64" => "data:image/png;base64,..."
# }Parâmetros
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
valor | float | Sim | Valor em reais |
nome_pagador | string | Sim | Nome do pagador |
documento_pagador | string | Sim | CPF ou CNPJ do pagador |
forcar_pagador | boolean | Não | Forçar dados do pagador |
email_pagador | string | Não | Email do pagador |
celular | string | Não | Celular do pagador |
descricao | string | Não | Descrição da cobrança |
webhook | string | Não | URL de callback |
magic_id | string | Não | ID mágico para referência |
api_key | string | Não | Chave de API |
split_users | list | Não | Split de pagamento |
Split de Pagamento
{:ok, charge} = NXGate.pix_generate(client, %{
valor: 100.00,
nome_pagador: "Maria Santos",
documento_pagador: "98765432100",
split_users: [
%{username: "loja_principal", percentage: 90.0},
%{username: "parceiro", percentage: 10.0}
]
})Saque PIX (Cash-out)
Realiza uma transferência PIX para a chave informada:
{:ok, withdrawal} = NXGate.pix_withdraw(client, %{
valor: 50.0,
chave_pix: "joao@email.com",
tipo_chave: :email,
webhook: "https://meusite.com/webhook"
})
# Resposta:
# %{
# "status" => "success",
# "message" => "...",
# "internalreference" => "ref_xyz"
# }Tipos de Chave PIX
| Atom | Valor | Descrição |
|---|---|---|
:cpf | CPF | CPF do destinatário |
:cnpj | CNPJ | CNPJ do destinatário |
:phone | PHONE | Telefone do destinatário |
:email | EMAIL | Email do destinatário |
:random | RANDOM | Chave aleatória |
Consultar Saldo
{:ok, balance} = NXGate.get_balance(client)
# Resposta:
# %{
# "balance" => 1000.00,
# "blocked" => 50.00,
# "available" => 950.00
# }Consultar Transação
# Cash-in
{:ok, tx} = NXGate.get_transaction(client, :cash_in, "id_transacao")
# Cash-out
{:ok, tx} = NXGate.get_transaction(client, :cash_out, "id_transacao")
# Resposta:
# %{
# "idTransaction" => "...",
# "status" => "PAID",
# "amount" => 100.0,
# "paidAt" => "2026-01-15T10:30:00Z",
# "endToEnd" => "..."
# }Webhooks
O módulo NXGate.Webhook facilita o processamento de notificações recebidas da NXGATE.
Configuração no Phoenix
defmodule MyAppWeb.WebhookController do
use MyAppWeb, :controller
def nxgate(conn, params) do
case NXGate.Webhook.parse(params) do
{:ok, %{type: "QR_CODE_COPY_AND_PASTE_PAID", category: :cash_in} = event} ->
# Pagamento PIX recebido
IO.inspect(event.data.amount, label: "Valor recebido")
IO.inspect(event.data.tx_id, label: "ID da transação")
json(conn, %{ok: true})
{:ok, %{type: "QR_CODE_COPY_AND_PASTE_REFUNDED"} = event} ->
# Pagamento estornado
handle_refund(event)
json(conn, %{ok: true})
{:ok, %{type: "PIX_CASHOUT_SUCCESS"} = event} ->
# Saque realizado com sucesso
IO.inspect(event.data.id_transaction, label: "Saque confirmado")
json(conn, %{ok: true})
{:ok, %{type: "PIX_CASHOUT_ERROR"} = event} ->
# Erro no saque
handle_cashout_error(event)
json(conn, %{ok: true})
{:ok, %{type: "PIX_CASHOUT_REFUNDED"} = event} ->
# Saque estornado
handle_cashout_refund(event)
json(conn, %{ok: true})
{:error, reason} ->
Logger.warning("Webhook NXGATE inválido: #{inspect(reason)}")
conn |> put_status(400) |> json(%{error: "invalid payload"})
end
end
endTipos de Evento
Cash-in (PIX Recebido)
| Tipo | Descrição |
|---|---|
QR_CODE_COPY_AND_PASTE_PAID | QR Code pago com sucesso |
QR_CODE_COPY_AND_PASTE_REFUNDED | QR Code estornado |
Cash-out (PIX Enviado)
| Tipo | Descrição |
|---|---|
PIX_CASHOUT_SUCCESS | Saque realizado com sucesso |
PIX_CASHOUT_ERROR | Erro no saque |
PIX_CASHOUT_REFUNDED | Saque estornado |
Funções Auxiliares
# Verificar se é evento de cash-in
NXGate.Webhook.cash_in?("QR_CODE_COPY_AND_PASTE_PAID") # true
# Verificar se é evento de cash-out
NXGate.Webhook.cash_out?("PIX_CASHOUT_SUCCESS") # true
# Listar todos os tipos conhecidos
NXGate.Webhook.known_types()Assinatura HMAC
Quando o hmac_secret é configurado, todas as requisições incluem automaticamente os seguintes headers:
| Header | Descrição |
|---|---|
X-Client-ID | Identificador do client |
X-HMAC-Signature | Assinatura HMAC-SHA256 codificada em Base64 |
X-HMAC-Timestamp | Timestamp ISO 8601 da requisição |
X-HMAC-Nonce | String única por requisição |
A string de assinatura é composta por:
METHOD\nPATH\nTIMESTAMP\nNONCE\nBODYTratamento de Erros
Todas as funções retornam {:ok, result} ou {:error, %NXGate.Error{}}.
case NXGate.pix_generate(client, params) do
{:ok, charge} ->
# Sucesso
IO.puts("QR Code: #{charge["paymentCode"]}")
{:error, %NXGate.Error{reason: :validation_error} = err} ->
# Erro de validação dos parâmetros
IO.puts("Parâmetros inválidos: #{err.message}")
{:error, %NXGate.Error{reason: :auth_error}} ->
# Erro de autenticação
IO.puts("Verifique suas credenciais")
{:error, %NXGate.Error{reason: :api_error, status_code: code} = err} ->
# Erro retornado pela API
IO.puts("Erro HTTP #{code}: #{err.message}")
{:error, %NXGate.Error{reason: :connection_error}} ->
# Erro de rede/conexão
IO.puts("Verifique sua conexão")
{:error, %NXGate.Error{reason: :timeout}} ->
# Timeout na requisição
IO.puts("A requisição expirou")
{:error, %NXGate.Error{reason: :max_retries}} ->
# Serviço indisponível após retentativas
IO.puts("Serviço temporariamente indisponível")
endTipos de Erro
| Reason | Descrição |
|---|---|
:validation_error | Parâmetros de entrada inválidos |
:auth_error | Falha na autenticação OAuth2 |
:api_error | Erro retornado pela API NXGATE |
:connection_error | Erro de rede/conexão |
:timeout | Timeout na requisição |
:max_retries | Máximo de retentativas atingido (503) |
Retry Automático
O SDK realiza retry automático com backoff exponencial quando recebe HTTP 503 (Service Unavailable):
- 1a tentativa: aguarda 1 segundo
- 2a tentativa: aguarda 2 segundos
-
Após esgotar as tentativas, retorna
{:error, %NXGate.Error{reason: :max_retries}}
O número máximo de retentativas pode ser configurado via opção :max_retries.
Gerenciamento de Token
O token OAuth2 é gerenciado automaticamente pelo NXGate.TokenManager:
- O token é obtido automaticamente ao iniciar o client
- Renovação automática 5 minutos antes da expiração
- Em caso de falha na renovação, nova tentativa após 5 segundos
-
Forçar renovação manualmente:
NXGate.refresh_token(client)
Desenvolvimento
# Clonar o repositório
git clone https://github.com/nxgate/sdk-elixir.git
cd sdk-elixir
# Instalar dependências
mix deps.get
# Executar testes
mix test
# Verificar formatação
mix format --check-formattedLicença
Este projeto está licenciado sob a licença MIT - veja o arquivo LICENSE para detalhes.