Documentação v1.0

Introdução

Bem-vindo à API da DryPay. Nossa solução foi projetada para ser simples, robusta e segura, permitindo que você integre pagamentos PIX em minutos.

Segurança Total

Criptografia de ponta a ponta em todas as requisições.

Ultra Rápido

Respostas em milissegundos para alta performance.

Simples

Endpoints RESTful padronizados e fáceis de usar.


POST

Autenticação (JWT)

Para interagir com nossa API, você precisa de um Bearer Token. Gere o token enviando seu Client ID e Client Secret (disponíveis no Dashboard) para o endpoint de login.

POST https://api.drypay.online/api/auth/login
Request Body
{
    "client_id": "SEU_CLIENT_ID",
    "client_secret": "SEU_CLIENT_SECRET"
}
Importante:

O token JWT tem validade limitada. Recomenda-se armazená-lo em cache e renová-lo somente quando expirar.


Endpoints

POST

Criar Transação PIX

POST https://api.drypay.online/v1/gateway

Parâmetros

,
Parâmetro Tipo Descrição
amount Obrigatório Float Valor em reais (ex: 15.00)
client Obrigatório Object Dados do pagador (name, document, email).
callbackUrl Obrigatório String URL de retorno para atualizações de status (Webhook).
curl -X POST https://api.drypay.online/v1/gateway/ \
-H "Authorization: Bearer {TOKEN}" \
-H "Content-Type: application/json" \
-d '{
    "amount": 100.00,
    "client": {
        "name": "João Silva",
        "document": "12345678901",
        "email": "joao@email.com"
    },
    "callbackUrl": "https://seusite.com/webhook"
}'
$data = [
    "amount" => 100.00,
    "client" => [
        "name" => "João Silva",
        "document" => "12345678901",
        "email" => "joao@email.com"
    ],
    "callbackUrl" => "https://seusite.com/webhook"
];

$ch = curl_init("https://api.drypay.online/v1/gateway/");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Bearer ' . $token
]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
import requests

url = "https://api.drypay.online/v1/gateway/"
headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json"
}
data = {
    "amount": 100.00,
    "client": {
        "name": "João Silva",
        "document": "12345678901",
        "email": "joao@email.com"
    },
    "callbackUrl": "https://seusite.com/webhook"
}

response = requests.post(url, headers=headers, json=data)
result = response.json()
const response = await fetch('https://api.drypay.online/v1/gateway/', {
    method: 'POST',
    headers: { 
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
        amount: 100.00,
        client: {
            name: "João Silva",
            document: "12345678901",
            email: "joao@email.com"
        },
        callbackUrl: "https://seusite.com/webhook"
    })
});
const data = await response.json();

Resposta (Sucesso)

{
    "status": "success",
    "paymentCode": "00020126360014BR.GOV.BCB.PIX...",
    "idTransaction": "52fc5262-4063-4900-933b-55e69850",
    "paymentCodeBase64": "iVBORw0KGgo..."
}

WEBHOOK

Recebendo Notificações

Importante

Sua aplicação deve retornar HTTP 200 OK para confirmar o recebimento. Caso contrário, tentaremos reenviar em intervalos de 15 segundos (5 tentativas).

Payload Enviado (POST)
{
    "status": "paid",
    "idTransaction": "52fc5262-4063-4900-933b-55e69850",
    "type": "Deposit"
}

POST

Consultar Status

POST https://api.drypay.online/v1/webhook
Body
{
    "idTransaction": "52fc5262-4063-4900-933b-55e69850"
}
Resposta
{
    "status": "PAID_OUT" // ou WAITING_FOR_APPROVAL
}

POST

Realizar Saque (Cashout)

POST https://api.drypay.online/c1/cashout/
curl -X POST https://api.drypay.online/c1/cashout/ \
-H "Authorization: Bearer {TOKEN}" \
-H "Content-Type: application/json" \
-d '{
    "amount": 50.00,
    "name": "Destinatário",
    "cpf": "12345678901",
    "keypix": "chave@pix.com",
    "type": "EMAIL"
}'
$data = [
    "amount" => 50.00,
    "name" => "Destinatário",
    "cpf" => "12345678901",
    "keypix" => "chave@pix.com",
    "type" => "EMAIL"
];

$ch = curl_init("https://api.drypay.online/c1/cashout/");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Bearer ' . $token
]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
import requests

url = "https://api.drypay.online/c1/cashout/"
headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json"
}
data = {
    "api-key": "SEU_CLIENT_ID",
    "amount": 50.00,
    "name": "Destinatário",
    "cpf": "12345678901",
    "keypix": "chave@pix.com",
    "type": "EMAIL"
}

response = requests.post(url, headers=headers, json=data)
result = response.json()
const response = await fetch('https://api.drypay.online/c1/cashout/', {
    method: 'POST',
    headers: { 
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
        amount: 50.00,
        name: "Destinatário",
        cpf: "12345678901",
        keypix: "chave@pix.com",
        type: "EMAIL"
    })
});
const data = await response.json();

Códigos de Erro

HTTP Descrição
200 Sucesso.
400 Requisição Inválida (verifique os parâmetros).
401 Não autorizado (API Key inválida).
429 Muitas requisições (Rate Limit).
500 Erro interno do servidor.

Exemplos de Erro

400 - Dados Inválidos

{
    "status": "error",
    "code": 400,
    "message": "Parâmetros obrigatórios ausentes",
    "errors": {
        "amount": "O campo amount é obrigatório",
        "client.email": "O campo email é obrigatório"
    }
}

401 - Não Autorizado

{
    "status": "error",
    "code": 401,
    "message": "API key inválida ou ausente",
    "error": "Token de autorização não fornecido ou expirado"
}

429 - Limite Excedido

{
    "status": "error",
    "code": 429,
    "message": "Limite de requisições excedido",
    "retry_after": 60
}

Tratamento de Erros (Exemplos)

# Exemplo de resposta de erro (HTTP 400)
# Para tratar erros, verifique o código HTTP retornado

curl -X POST https://api.drypay.online/v1/gateway/ \
-H "Authorization: Bearer {TOKEN}" \
-H "Content-Type: application/json" \
-d '{"amount": -10}' \
-w "\n\nHTTP Status: %{http_code}\n"

# Resposta esperada:
# {"status":"error","code":400,"message":"Valor inválido"}
# HTTP Status: 400
function makeApiRequest($url, $data, $token) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Authorization: Bearer ' . $token
    ]);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    $responseBody = json_decode($response, true);
    
    if ($httpCode !== 200) {
        switch ($httpCode) {
            case 400:
                error_log("Dados inválidos: " . print_r($responseBody['errors'] ?? [], true));
                break;
            case 401:
                error_log("Token inválido ou expirado");
                break;
            case 429:
                $retryAfter = $responseBody['retry_after'] ?? 60;
                sleep($retryAfter);
                return makeApiRequest($url, $data, $token); // Retry
            case 500:
                error_log("Erro interno do servidor");
                break;
        }
        throw new Exception("Erro API: " . ($responseBody['message'] ?? 'Erro desconhecido'));
    }
    
    return $responseBody;
}
import requests
import time

def make_api_request(url, data, token, max_retries=3):
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json"
    }
    
    for attempt in range(max_retries):
        try:
            response = requests.post(url, headers=headers, json=data)
            
            if response.status_code == 200:
                return response.json()
            
            error = response.json()
            
            if response.status_code == 400:
                print(f"Dados inválidos: {error.get('errors', {})}")
            elif response.status_code == 401:
                print("Token inválido ou expirado")
            elif response.status_code == 429:
                retry_after = error.get('retry_after', 60)
                print(f"Rate limit. Aguardando {retry_after}s...")
                time.sleep(retry_after)
                continue  # Retry
            elif response.status_code == 500:
                print("Erro interno do servidor")
            
            raise Exception(f"Erro API: {error.get('message', 'Erro desconhecido')}")
            
        except requests.exceptions.RequestException as e:
            print(f"Erro de conexão: {e}")
            if attempt < max_retries - 1:
                time.sleep(5)
                continue
            raise
    
    return None
async function makeApiRequest(url, data, token, maxRetries = 3) {
    for (let attempt = 0; attempt < maxRetries; attempt++) {
        try {
            const response = await fetch(url, {
                method: 'POST',
                headers: { 
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${token}`
                },
                body: JSON.stringify(data)
            });

            if (response.ok) {
                return await response.json();
            }

            const error = await response.json();

            switch (response.status) {
                case 400:
                    console.error('Dados inválidos:', error.errors);
                    break;
                case 401:
                    console.error('Token inválido ou expirado');
                    break;
                case 429:
                    const retryAfter = error.retry_after || 60;
                    console.warn(`Rate limit. Aguardando ${retryAfter}s...`);
                    await new Promise(r => setTimeout(r, retryAfter * 1000));
                    continue; // Retry
                case 500:
                    console.error('Erro interno do servidor');
                    break;
            }

            throw new Error(error.message || 'Erro desconhecido');
        } catch (e) {
            console.error('Erro na requisição:', e);
            if (attempt < maxRetries - 1) {
                await new Promise(r => setTimeout(r, 5000));
                continue;
            }
            throw e;
        }
    }
}