Metadata-Version: 2.4
Name: mupay-sdk
Version: 0.1.0
Summary: SDK oficial Python para integrar com a API pública da MuPay.
Project-URL: Homepage, https://docs.mupay.com
Project-URL: Repository, https://github.com/mupay/mupay
Author: MuPay
License: Proprietary
Keywords: gateway,mupay,payments,pix
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx<1.0,>=0.27
Requires-Dist: pydantic<3.0,>=2.7
Requires-Dist: tenacity<10.0,>=8.3
Provides-Extra: dev
Requires-Dist: coverage[toml]>=7.5; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.2; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# mupay-sdk

SDK oficial Python para integrar backends, automacoes, scripts e notebooks com a API publica da MuPay.

Ele foi desenhado para deixar o caminho feliz curto: instala, cria um cliente com `sk_test_*`, chama `mupay.charges.create(...)` e recebe um objeto tipado. Sem montar `httpx` na mao, sem decorar header de idempotencia, sem parsing manual de erro, sem validar webhook no improviso.

## Por que integrar com a SDK é simples

- API com cara de produto: `mupay.charges.create(...)`, `mupay.subscriptions.cancel(..., mode="immediate")` e `mupay.webhooks.construct_event(...)`.
- Tipos Pydantic v2 para validar request/response cedo, ainda no seu codigo.
- Cliente sync e async com a mesma ergonomia.
- Idempotencia automatica em operacoes mutaveis, com opcao de informar sua propria chave.
- Retry seguro para 429/5xx: respeita `Retry-After` quando a API envia e usa backoff curto quando nao envia.
- Erros tipados com `code`, `suggestion`, `documentation_url` e `request_id`, prontos para log/suporte.
- Webhook HMAC-SHA256 em tempo constante, com janela anti-replay padrao de 5 minutos.

O resultado esperado para quem integra e: poucas linhas para receber um PIX de teste e informacoes suficientes para resolver erro sem abrir ticket.

## Instalação

```bash
pip install mupay-sdk
```

Requisitos:

- Python 3.10, 3.11 ou 3.12.
- Uma API key `sk_test_*` ou `sk_live_*`.
- Dependencias runtime pequenas: `httpx`, `pydantic` v2 e `tenacity`.

## Quickstart

```python
from mupay_sdk import Gateway

mupay = Gateway(api_key="sk_test_...")

charge = mupay.charges.create(
    amount_cents=12000,
    payment_method="pix",
    customer={"id": "22222222-2222-4222-8222-222222222222"},
)

print(charge.pix_emv_code)
```

## Cliente async

```python
from mupay_sdk import AsyncGateway


async def main() -> None:
    async with AsyncGateway(api_key="sk_test_...") as mupay:
        charge = await mupay.charges.create(
            amount_cents=12000,
            payment_method="pix",
            customer={"id": "22222222-2222-4222-8222-222222222222"},
        )
        print(charge.charge_id)
```

## Erros tipados

Erros HTTP da API viram `GatewayAPIError`. O erro preserva `status_code`, `code`, `suggestion`, `documentation_url` e `request_id` quando a API envia Problem Details.

```python
from mupay_sdk import Gateway
from mupay_sdk.errors import GatewayAPIError

mupay = Gateway(api_key="sk_test_...")

try:
    mupay.charges.create(
        amount_cents=12000,
        payment_method="credit_card",
        card_token="tok_test",
        customer={"id": "22222222-2222-4222-8222-222222222222"},
    )
except GatewayAPIError as exc:
    print(exc.code, exc.request_id, exc.suggestion)
```

## Webhooks

Valide a assinatura antes de confiar no payload. O helper usa HMAC-SHA256 em tempo constante e bloqueia replay fora da janela configurada.

```python
from mupay_sdk.webhooks import construct_event

event = construct_event(
    request_body,
    request_headers["x-mupay-signature"],
    "whsec_...",
)

print(event.type)
```

## Cancelamento de assinatura

O SDK envia o mesmo payload exigido pela API publica: `mode` é obrigatório e `reason` é opcional.

```python
from mupay_sdk import Gateway

mupay = Gateway(api_key="sk_test_...")

subscription = mupay.subscriptions.cancel(
    "sub_123",
    mode="immediate",
    reason="cliente pediu cancelamento",
)

print(subscription.status)
```

## Fluxo completo em menos de 5 minutos

1. Instale o pacote: `pip install mupay-sdk`.
2. Crie uma API key sandbox no dashboard da MuPay.
3. Exporte a chave: `set MUPAY_API_KEY=sk_test_...` no Windows ou `export MUPAY_API_KEY=sk_test_...` no Linux/macOS.
4. Rode `python examples/create_pix_charge.py`.
5. Copie o `pix_emv_code` retornado para simular pagamento no sandbox.

Essa e a experiencia que a SDK precisa proteger: o integrador nao deve precisar conhecer headers internos, formato exato de Problem Details ou detalhes de retry para criar a primeira cobranca.

## Exemplos completos

- `examples/create_pix_charge.py`
- `examples/async_create_charge.py`
- `examples/verify_webhook.py`

## Desenvolvimento local

```bash
python -m pip install -e .[dev]
python -m pytest
python -m coverage run -m pytest
python -m coverage report
python -m mypy .
python -m ruff check .
```

## Publicação PyPI manual

Este PR não adiciona build/publicação automática no GitHub Actions. A publicação pública inicial deve ser manual para evitar release acidental enquanto o contrato da API ainda está amadurecendo.

Para publicar publicamente:

1. Crie conta e verifique email em PyPI e TestPyPI.
2. Garanta que o nome `mupay-sdk` está disponível ou que a organização MuPay controla esse nome.
3. Atualize `version` em `pyproject.toml` usando versionamento semântico.
4. Rode a validação local:

```bash
python -m pip install -e .[dev]
python -m ruff check .
python -m mypy .
python -m coverage run -m pytest
python -m coverage report
uv build
```

5. Publique primeiro no TestPyPI:

```bash
python -m pip install twine
python -m twine upload --repository testpypi dist/*
```

6. Instale em ambiente limpo e rode um smoke test:

```bash
python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ mupay-sdk
python -c "from mupay_sdk import Gateway; print(Gateway)"
```

7. Se o smoke test passar, publique no PyPI:

```bash
python -m twine upload dist/*
```

Use token de API com escopo limitado ao projeto `mupay-sdk` quando o projeto já existir. Nunca coloque token PyPI em código, README, commit ou workflow.
