curl -X POST https://api.nixfypagamentos.com/api/public/cashout \
-H "X-Api-Public-Key: sua_chave_publica_aqui" \
-H "X-Api-Private-Key: sua_chave_privada_aqui" \
-H "Content-Type: application/json" \
-d '{
"amount": 100.00,
"pixKey": "11999999999",
"pixKeyType": "PHONE"
}'
{
"id": 12345,
"uuid": "01a1271c-b3f0-7c21-9e4d-5a7b8c9d0e1f",
"amount": "100.00",
"netAmount": "95.00",
"pixKey": "11999999999",
"pixKeyType": "PHONE",
"status": "PENDING",
"createdAt": "2024-01-15T10:30:00.000Z",
"fees": {
"fixed": "2.00",
"variable": "3.00",
"total": "5.00"
}
}
Transferências
Criar Transferência
Solicite um saque (cashout) do seu saldo disponível para uma chave PIX
POST
/
api
/
public
/
cashout
curl -X POST https://api.nixfypagamentos.com/api/public/cashout \
-H "X-Api-Public-Key: sua_chave_publica_aqui" \
-H "X-Api-Private-Key: sua_chave_privada_aqui" \
-H "Content-Type: application/json" \
-d '{
"amount": 100.00,
"pixKey": "11999999999",
"pixKeyType": "PHONE"
}'
{
"id": 12345,
"uuid": "01a1271c-b3f0-7c21-9e4d-5a7b8c9d0e1f",
"amount": "100.00",
"netAmount": "95.00",
"pixKey": "11999999999",
"pixKeyType": "PHONE",
"status": "PENDING",
"createdAt": "2024-01-15T10:30:00.000Z",
"fees": {
"fixed": "2.00",
"variable": "3.00",
"total": "5.00"
}
}
Solicita um saque (cashout) do seu saldo disponível para uma chave PIX.
Recomendações de segurança:
Autenticação
Este endpoint requer autenticação via API Keys:string
required
Sua chave pública da API
string
required
Sua chave privada da API
Parâmetros do Body
number
required
Valor do cashout em reais (ex: 100.50 = R100,50).∗∗Mıˊnimo:R 100,00**. Máximo: R$ 100.000,00
string
required
Chave PIX para recebimento (entre 8 e 77 caracteres)
string
Tipo da chave PIX. Valores possíveis:
CPF, CNPJ, EMAIL, PHONE, RANDOM. Padrão: CPFO valor mínimo para transferência é R$ 100,00. Valores abaixo deste mínimo retornarão erro
TRANSFER_NOT_ALLOWED.Exemplo de Requisição
curl -X POST https://api.nixfypagamentos.com/api/public/cashout \
-H "X-Api-Public-Key: sua_chave_publica_aqui" \
-H "X-Api-Private-Key: sua_chave_privada_aqui" \
-H "Content-Type: application/json" \
-d '{
"amount": 100.00,
"pixKey": "11999999999",
"pixKeyType": "PHONE"
}'
Resposta de Sucesso
integer
ID numérico do cashout (mantido para integrações antigas)
string
Identificador público do cashout (UUID). Use-o para consultar o saque e casar os webhooks
string
Valor em reais
string
Chave PIX
string
Status do cashout (PENDING, PROCESSING, etc.)
string
Data de criação (ISO 8601)
Exemplo de Resposta
{
"id": 12345,
"uuid": "01a1271c-b3f0-7c21-9e4d-5a7b8c9d0e1f",
"amount": "100.00",
"netAmount": "95.00",
"pixKey": "11999999999",
"pixKeyType": "PHONE",
"status": "PENDING",
"createdAt": "2024-01-15T10:30:00.000Z",
"fees": {
"fixed": "2.00",
"variable": "3.00",
"total": "5.00"
}
}
string
Valor líquido após taxas em reais
string
Tipo da chave PIX utilizada
object
Detalhamento das taxas cobradas
string
Taxa fixa em reais
string
Taxa variável em reais
string
Total de taxas em reais
Configuração de Webhooks
Para receber notificações automáticas sobre mudanças de status dos saques, você precisa configurar um webhook no painel do usuário.Como Configurar
- Acesse o painel do Nixfy Gateway
- Vá em Menu lateral > Integrações > Adicionar Webhook
- Configure a URL do seu webhook (ex:
https://seusite.com/webhook/cashout) - Em “Tipos de Notificação”, marque “Notificar Saques”
- Salve a configuração
Sem webhook configurado, você NÃO receberá notificações automáticas de mudança de status dos saques (PROCESSING → COMPLETED/REJECTED).
Quando o Webhook é Enviado
O webhook é enviado quando o status do saque muda, após o processamento do postback do provedor BaaS (Sqala, Witetec, Transfeera, etc.). As notificações são enviadas para os seguintes status:PROCESSING- Saque em processamentoCOMPLETED- Saque concluído com sucessoREJECTED- Saque rejeitadoCANCELLED- Saque cancelado
Formato do Payload
{
"id": 123,
"uuid": "01a1271c-b3f0-7c21-9e4d-5a7b8c9d0e1f",
"userId": 1,
"amount": "100.00",
"pixKey": "11999999999",
"pixKeyType": "PHONE",
"status": "COMPLETED",
"externalId": "GATEWAY-123",
"createdAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2025-01-15T10:35:00.000Z",
"processedAt": "2025-01-15T10:35:00.000Z",
"user": {
"id": 1,
"name": "João Silva",
"email": "joao@exemplo.com"
},
"type": "WITHDRAWAL"
}
Campos do Payload
| Campo | Tipo | Descrição |
|---|---|---|
id | integer | ID numérico do saque no Nixfy Gateway (mantido para integrações antigas) |
uuid | string | Identificador público do saque (UUID), o mesmo devolvido na criação |
userId | integer | ID do usuário que solicitou o saque |
amount | string | Valor do saque em reais (formato string, ex: “100.00”) |
pixKey | string | null | Chave PIX utilizada para o saque |
pixKeyType | string | null | Tipo da chave PIX (CPF, CNPJ, EMAIL, PHONE, RANDOM) |
status | string | Status atual do saque (PENDING, PROCESSING, COMPLETED, CANCELLED, REJECTED) |
externalId | string | null | ID externo do saque no provedor BaaS |
createdAt | string | Data de criação do saque (ISO 8601) |
updatedAt | string | Data da última atualização (ISO 8601) |
processedAt | string | null | Data de processamento do saque (ISO 8601) |
user | object | Dados do usuário (id, name, email) |
type | string | Sempre “WITHDRAWAL” para identificar o tipo de notificação |
Segurança
Webhooks permanentes de saques não incluem assinatura HMAC. Diferente dos postbacks por transação (que usam
X-Signature), os webhooks permanentes são enviados sem assinatura.- Validar a origem usando a URL configurada
- Usar HTTPS
- Validar o
userIdpara garantir que o saque pertence à sua conta - Implementar idempotência para evitar processamento duplicado
Exemplo de Implementação
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhook/cashout', (req, res) => {
const payload = req.body;
// Validar tipo de notificação
if (payload.type !== 'WITHDRAWAL') {
return res.status(400).json({ error: 'Tipo de notificação inválido' });
}
// Validar userId (garantir que é da sua conta)
const expectedUserId = process.env.YOUR_USER_ID;
if (payload.userId !== parseInt(expectedUserId)) {
return res.status(403).json({ error: 'Usuário não autorizado' });
}
// Processar notificação
console.log('Saque atualizado:', {
id: payload.id,
status: payload.status,
amount: payload.amount,
pixKey: payload.pixKey
});
// Implementar lógica de negócio aqui
// Ex: atualizar status no seu sistema, enviar email, etc.
// Sempre retornar 200 para confirmar recebimento
res.status(200).json({ success: true });
});
app.listen(3000);
from flask import Flask, request, jsonify
import os
app = Flask(__name__)
@app.route('/webhook/cashout', methods=['POST'])
def webhook_cashout():
payload = request.json
# Validar tipo de notificação
if payload.get('type') != 'WITHDRAWAL':
return jsonify({'error': 'Tipo de notificação inválido'}), 400
# Validar userId
expected_user_id = int(os.environ.get('YOUR_USER_ID', 0))
if payload.get('userId') != expected_user_id:
return jsonify({'error': 'Usuário não autorizado'}), 403
# Processar notificação
print(f"Saque atualizado: ID={payload['id']}, Status={payload['status']}, Amount={payload['amount']}")
# Implementar lógica de negócio aqui
return jsonify({'success': True}), 200
if __name__ == '__main__':
app.run(port=3000)
<?php
$payload = json_decode(file_get_contents('php://input'), true);
// Validar tipo de notificação
if ($payload['type'] !== 'WITHDRAWAL') {
http_response_code(400);
echo json_encode(['error' => 'Tipo de notificação inválido']);
exit;
}
// Validar userId
$expectedUserId = (int) getenv('YOUR_USER_ID');
if ($payload['userId'] !== $expectedUserId) {
http_response_code(403);
echo json_encode(['error' => 'Usuário não autorizado']);
exit;
}
// Processar notificação
error_log("Saque atualizado: ID={$payload['id']}, Status={$payload['status']}, Amount={$payload['amount']}");
// Implementar lógica de negócio aqui
http_response_code(200);
echo json_encode(['success' => true]);
?>
Boas Práticas
- Sempre retorne HTTP 200 para confirmar recebimento
- Implemente idempotência usando o campo
iddo saque - Valide o
userIdpara garantir segurança - Use HTTPS para proteger os dados em trânsito
- Implemente retry logic no seu servidor caso a notificação falhe
- Log todas as notificações recebidas para auditoria
Diferenças entre Webhook Permanente e Postback
| Característica | Webhook Permanente | Postback por Transação |
|---|---|---|
| Configuração | Painel do usuário | Campo postbackUrl na criação |
| Assinatura HMAC | Não | Sim (X-Signature header) |
| Escopo | Todas as transações/saques do usuário | Apenas transação/saque específica |
Campo type | Sim (“WITHDRAWAL”) | Não |
Campo user | Sim (dados do usuário) | Não |
Códigos de Erro
400 Bad Request
Dados inválidos. Exemplo: valor deve ser um número válido maior que zero.{
"message": "Dados inválidos",
"error": "O valor deve ser um número válido maior que zero"
}
401 Unauthorized
Não autorizado - API Key ou API Secret inválidos.{
"message": "Não autorizado",
"error": "Chaves de API inválidas ou ausentes"
}
403 Forbidden
Cashout via API desabilitado ou usuário sem permissão. Pode retornar:API_WITHDRAWAL_DISABLED_GLOBALLY- Cashout via API está desabilitado para este usuárioTRANSFER_NOT_ALLOWED- Transferência não permitida
{
"message": "Transferência não permitida",
"errorType": "TRANSFER_NOT_ALLOWED"
}
422 Unprocessable Entity
Saldo insuficiente ou regras de negócio. Pode retornar:INSUFFICIENT_BALANCE- Saldo insuficiente para realizar o cashoutMINIMUM_VALUE- Valor abaixo do mínimo permitido (R$ 100,00)MAXIMUM_VALUE- Valor acima do máximo permitido (R$ 100.000,00)
{
"message": "Saldo insuficiente para realizar o cashout",
"errorType": "INSUFFICIENT_BALANCE"
}
500 Internal Server Error
Erro interno do servidor.{
"message": "Erro interno do servidor",
"error": "Falha ao processar cashout. Tente novamente mais tarde."
}

