Metadata-Version: 2.4
Name: nxgate-sdk-python
Version: 1.0.0
Summary: SDK oficial da NXGATE para integração com a API PIX
Author-email: NXGATE <suporte@nxgate.com.br>
License: MIT
Project-URL: Homepage, https://github.com/nxgate/nxgate-sdk-python
Project-URL: Documentation, https://github.com/nxgate/nxgate-sdk-python#readme
Project-URL: Repository, https://github.com/nxgate/nxgate-sdk-python
Keywords: nxgate,pix,pagamentos,qrcode,sdk
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# NXGATE PIX SDK para Python

SDK oficial da NXGATE para integração com a API PIX. Permite gerar cobranças (cash-in), realizar saques (cash-out), consultar saldo e transações, tudo com tipagem completa e zero dependências externas.

## Requisitos

- Python 3.10 ou superior
- Sem dependências externas (usa apenas a biblioteca padrão)

## Instalação

```bash
pip install nxgate
```

Ou instale diretamente do repositório:

```bash
pip install git+https://github.com/nxgate/sdk-python.git
```

## Início Rápido

```python
from nxgate import NXGate, NXGateWebhook

nx = NXGate(
    client_id="nxgate_xxx",
    client_secret="secret",
    hmac_secret="opcional",  # opcional - quando informado, todas as requisições são assinadas com HMAC-SHA256
)
```

## Funcionalidades

### Gerar cobrança PIX (Cash-in)

Gera uma cobrança PIX e retorna o QR Code para pagamento.

```python
charge = nx.pix_generate(
    valor=100.00,
    nome_pagador="João da Silva",
    documento_pagador="12345678901",
    webhook="https://meusite.com/webhook",
    descricao="Pedido #1234",
    email_pagador="joao@email.com",
    celular="11999999999",
)

print(charge.status)            # "ACTIVE"
print(charge.paymentCode)       # código copia-e-cola
print(charge.idTransaction)     # ID da transação
print(charge.paymentCodeBase64) # QR Code em base64
```

#### Cobrança com split de pagamento

```python
charge = nx.pix_generate(
    valor=200.00,
    nome_pagador="Maria Souza",
    documento_pagador="98765432100",
    split_users=[
        {"username": "loja_a", "percentage": 70.0},
        {"username": "loja_b", "percentage": 30.0},
    ],
)
```

### Saque PIX (Cash-out)

Realiza uma transferência PIX para uma chave destino.

```python
withdrawal = nx.pix_withdraw(
    valor=50.00,
    chave_pix="joao@email.com",
    tipo_chave="EMAIL",  # CPF | CNPJ | PHONE | EMAIL | RANDOM
    webhook="https://meusite.com/webhook",
)

print(withdrawal.status)            # "PROCESSING"
print(withdrawal.internalreference) # referência interna
```

### Consultar saldo

```python
balance = nx.get_balance()

print(balance.balance)   # saldo total
print(balance.blocked)   # saldo bloqueado
print(balance.available) # saldo disponível
```

### Consultar transação

```python
tx = nx.get_transaction(type="cash-in", txid="px_xxx")

print(tx.idTransaction) # ID da transação
print(tx.status)        # status atual
print(tx.amount)        # valor
print(tx.paidAt)        # data do pagamento
print(tx.endToEnd)      # identificador end-to-end
```

## Webhooks

O SDK fornece um parser para eventos recebidos via webhook.

### Recebendo eventos (exemplo com Flask)

```python
from flask import Flask, request, jsonify
from nxgate import NXGateWebhook, NXGateError
from nxgate.types import CashInEvent, CashOutEvent

app = Flask(__name__)

@app.route("/webhook", methods=["POST"])
def webhook():
    try:
        event = NXGateWebhook.parse(request.json)
    except NXGateError as e:
        return jsonify({"error": str(e)}), 400

    if isinstance(event, CashInEvent):
        print(f"Cash-in: {event.type}")
        print(f"  Valor: R$ {event.data.amount:.2f}")
        print(f"  Pagador: {event.data.debtor_name}")
        print(f"  TX ID: {event.data.tx_id}")
        print(f"  Status: {event.data.status}")

    elif isinstance(event, CashOutEvent):
        print(f"Cash-out: {event.type}")
        print(f"  Valor: R$ {event.amount:.2f}")
        print(f"  Chave: {event.key}")
        if event.error:
            print(f"  Erro: {event.error}")

    return jsonify({"ok": True})
```

### Tipos de evento

**Cash-in:**
- `QR_CODE_COPY_AND_PASTE_PAID` - pagamento confirmado
- `QR_CODE_COPY_AND_PASTE_REFUNDED` - pagamento devolvido

**Cash-out:**
- `PIX_CASHOUT_SUCCESS` - saque realizado com sucesso
- `PIX_CASHOUT_ERROR` - erro no saque
- `PIX_CASHOUT_REFUNDED` - saque devolvido

## Assinatura HMAC

Quando o parâmetro `hmac_secret` é informado na inicialização do cliente, todas as requisições são automaticamente assinadas com HMAC-SHA256. Os seguintes headers são adicionados:

| Header | Descrição |
|--------|-----------|
| `X-Client-ID` | Seu `client_id` |
| `X-HMAC-Signature` | Assinatura HMAC-SHA256 em base64 |
| `X-HMAC-Timestamp` | Timestamp ISO 8601 |
| `X-HMAC-Nonce` | Valor único por requisição |

A assinatura é gerada sobre a string canônica:

```
METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY
```

## Gerenciamento de Token

O SDK gerencia automaticamente o token OAuth2:

- O token é obtido na primeira requisição
- É mantido em cache enquanto válido
- É renovado automaticamente 60 segundos antes de expirar
- Em caso de falha na autenticação, `NXGateAuthError` é lançado

## Tratamento de Erros

```python
from nxgate import NXGate, NXGateError
from nxgate.errors import NXGateAuthError, NXGateTimeoutError, NXGateRetryError

nx = NXGate(client_id="xxx", client_secret="yyy")

try:
    charge = nx.pix_generate(
        valor=100.00,
        nome_pagador="Teste",
        documento_pagador="00000000000",
    )
except NXGateAuthError as e:
    print(f"Erro de autenticação: {e}")
    print(f"Status HTTP: {e.status_code}")
except NXGateTimeoutError as e:
    print(f"Timeout: {e}")
except NXGateRetryError as e:
    print(f"Todas as tentativas falharam: {e}")
except NXGateError as e:
    print(f"Erro da API: {e}")
    print(f"Título: {e.title}")
    print(f"Código: {e.code}")
    print(f"Descrição: {e.description}")
    print(f"Status HTTP: {e.status_code}")
```

### Hierarquia de exceções

```
Exception
└── NXGateError
    ├── NXGateAuthError      # falha na autenticação
    ├── NXGateTimeoutError   # timeout na requisição
    └── NXGateRetryError     # tentativas esgotadas (503)
```

## Retry Automático

Requisições que retornam HTTP 503 são automaticamente retentadas com backoff exponencial:

- Máximo de 2 retentativas (3 tentativas no total)
- Delay entre tentativas: 1s, 2s
- Se todas as tentativas falharem, `NXGateRetryError` é lançado

## Referência da API

### `NXGate(client_id, client_secret, hmac_secret=None, *, base_url, timeout)`

| Parâmetro | Tipo | Obrigatório | Descrição |
|-----------|------|-------------|-----------|
| `client_id` | `str` | Sim | Seu client_id NXGATE |
| `client_secret` | `str` | Sim | Seu client_secret NXGATE |
| `hmac_secret` | `str \| None` | Não | Secret para assinatura HMAC |
| `base_url` | `str` | Não | URL base da API (padrão: `https://api.nxgate.com.br`) |
| `timeout` | `int` | Não | Timeout em segundos (padrão: `30`) |

### Métodos

| Método | Retorno | Descrição |
|--------|---------|-----------|
| `pix_generate(...)` | `PixGenerateResponse` | Gera cobrança PIX |
| `pix_withdraw(...)` | `PixWithdrawResponse` | Realiza saque PIX |
| `get_balance()` | `BalanceResponse` | Consulta saldo |
| `get_transaction(type, txid)` | `TransactionResponse` | Consulta transação |

## Desenvolvimento

### Executar testes

```bash
pip install pytest
pytest
```

### Estrutura do projeto

```
nxgate/
├── __init__.py      # exports públicos
├── client.py        # classe NXGate
├── auth.py          # gerenciamento de token
├── hmac_signer.py   # assinatura HMAC
├── webhook.py       # parser de webhook
├── errors.py        # exceções
└── types.py         # dataclasses tipadas
```

## Licença

MIT - veja o arquivo [LICENSE](LICENSE) para detalhes.
