📚 Projeto feito para fins de estudo. Sim, já existe um SDK Python oficial/anterior da AbacatePay — descobrimos depois 😅 Esta biblioteca foi construída como exercício de engenharia: explorar design de SDK, sync+async com
httpx, validação com Pydantic v2, verificação de webhook, packaging moderno, CI/CD com OIDC Trusted Publishing, MkDocs, etc. Se servir de referência para alguém estudando os mesmos temas, ótimo.⚠️ Biblioteca não-oficial, mantida pela comunidade, sem fins comerciais. Todos os créditos da plataforma de pagamentos, dos produtos e da API REST são da AbacatePay. Documentação oficial da API: https://docs.abacatepay.com.
✨ Features
- 🐍 Python 3.10+ com type hints completos (compatível com
mypy --strict) - ⚡ Sync e async na mesma interface (
AbacaPayeAsyncAbacaPay, ambos sobrehttpx) - 🧱 Modelos Pydantic v2 com validação, alias automático (camelCase ↔ snake_case) e tolerância a campos novos
- 🛡️ Hierarquia de erros tipada por status HTTP (
AuthenticationError,NotFoundError,RateLimitError, …) - 🔁 Retries com backoff exponencial + jitter em
429e5xx - 🔐 Verificação de webhook (HMAC-SHA256, comparação constant-time)
- 📦 Cobre 100% dos endpoints documentados: Checkouts, Payment Links, Customers, Checkout Transparente (PIX), Products, Coupons, Webhooks, Subscriptions, Payouts, PIX Transfers, Store e TrustMRR
- 🧪 Testado com
pytest+respx
📦 Instalação
pip install abacapython
Ou com uv:
uv add abacapython
🚀 Quickstart
Síncrono
from abacapython import AbacaPay
client = AbacaPay(api_key="abc_dev_...") # ou via env: ABACATEPAY_API_KEY
# 1. Crie um produto
produto = client.products.create({
"external_id": "plano-mensal",
"name": "Plano Mensal",
"price": 9990, # R$ 99,90 em centavos
"currency": "BRL",
})
# 2. Crie um checkout hospedado
checkout = client.checkouts.create({
"items": [{"id": produto.id, "quantity": 1}],
"methods": ["PIX", "CARD"],
"completion_url": "https://meusite.com/obrigado",
})
print(checkout.url) # redirecione o cliente para esta URL
Assíncrono
import asyncio
from abacapython import AsyncAbacaPay
async def main() -> None:
async with AsyncAbacaPay(api_key="abc_dev_...") as client:
loja = await client.store.get()
print(loja.name)
asyncio.run(main())
PIX Checkout Transparente (QR Code no seu site)
pix = client.pix_qrcodes.create({
"amount": 4990, # R$ 49,90
"description": "Pedido #1234",
"expires_in": 3600, # 1 hora
"customer": {"email": "alice@example.com", "tax_id": "12345678900"},
})
# Mostre estes para o cliente:
print(pix.br_code) # "copia-e-cola"
print(pix.br_code_base64) # imagem PNG do QR Code
# Mais tarde:
status = client.pix_qrcodes.check(id=pix.id)
if status.status == "PAID":
...
Assinaturas (recorrência)
from abacapython import CreateProductParams, ProductCycle
plano = client.products.create(CreateProductParams(
external_id="premium",
name="Premium Mensal",
price=4990,
currency="BRL",
cycle=ProductCycle.MONTHLY, # produto recorrente
))
sub = client.subscriptions.create({
"items": [{"id": plano.id, "quantity": 1}],
"completion_url": "https://meusite.com/bem-vindo",
})
print(sub.url)
Webhooks
import os
from flask import Flask, request, abort
from abacapython import webhooks
app = Flask(__name__)
SECRET = os.environ["ABACATEPAY_WEBHOOK_SECRET"]
@app.post("/abacatepay/webhook")
def receive():
signature = webhooks.extract_signature(request.headers)
try:
event = webhooks.parse_event(request.data, signature, SECRET)
except webhooks.WebhookSignatureError:
abort(401)
if event.event == "checkout.completed":
# Marque pedido como pago...
pass
elif event.event == "transparent.completed":
# PIX confirmado...
pass
return "", 204
Tratamento de erros
from abacapython.exceptions import (
AuthenticationError, NotFoundError, RateLimitError, APIResponseError,
)
try:
client.customers.get(id="cust_inexistente")
except NotFoundError:
...
except AuthenticationError:
...
except RateLimitError:
...
except APIResponseError as exc:
# Fallback genérico
print(exc.status_code, exc.message)
⚙️ Configuração
| Parâmetro | Default | Descrição |
|---|---|---|
api_key |
os.environ["ABACATEPAY_API_KEY"] |
Bearer Token da AbacatePay. |
base_url |
https://api.abacatepay.com/v2 |
Pode ser sobrescrito por ABACATEPAY_BASE_URL. |
timeout |
30.0 |
Timeout (s) para cada requisição. |
max_retries |
2 |
Tentativas extras para 429, 5xx, timeouts e erros de conexão. |
backoff_factor |
0.5 |
Fator base do backoff exponencial entre retries. |
backoff_max |
8.0 |
Limite (s) para qualquer espera entre retries. |
http_client |
None |
Instância customizada de httpx.Client / httpx.AsyncClient. |
🗺️ Mapa de endpoints
| Recurso na API | Acesso no SDK |
|---|---|
/customers/* |
client.customers |
/products/* |
client.products |
/checkouts/* |
client.checkouts |
/payment-links/* |
client.payment_links |
/transparents/* (PIX) |
client.pix_qrcodes |
/coupons/* |
client.coupons |
/webhooks/* |
client.webhooks |
/subscriptions/* |
client.subscriptions |
/payouts/* |
client.payouts |
/pix/* (transferência) |
client.pix_transfers |
/store/* |
client.store |
/trustMRR/* (público) |
client.trust_mrr |
🛣️ Compatibilidade
| Python | Status |
|---|---|
| 3.10 | ✅ testado |
| 3.11 | ✅ testado |
| 3.12 | ✅ testado |
| 3.13 | ✅ testado |
🤝 Como contribuir
Pull Requests são muito bem-vindos! Veja CONTRIBUTING.md para detalhes.
Em resumo:
git clone https://github.com/nicollasrezende/abacapython
cd abacapython
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,docs]"
ruff check . && ruff format --check .
mypy
pytest
📜 Licença
MIT. Faça bom proveito.
📖 Por que existe (TL;DR sincero)
Eu queria praticar:
- Design de SDK no estilo Stripe/Twilio (resources, modelos tipados, sync+async)
httpxcom retries + backoff exponencial + jitter- Pydantic v2 com alias (
camelCase↔snake_case) e validações declarativas - Verificação HMAC de webhook com comparação constant-time
- Packaging moderno (
hatchling,pyproject.toml,py.typed) - CI/CD com matrix multi-Python e PyPI via OIDC Trusted Publishing (sem token no repo)
- MkDocs Material com
mkdocstringsgerando referência da API - Workflow open-source: CONTRIBUTING, CODE_OF_CONDUCT, SECURITY, issue/PR templates
A abacapython foi o pretexto para fazer tudo isso. Já existe um SDK oficial da AbacatePay para Python, então não use esta lib em produção — use a deles. Se este código te ajudou a aprender algum dos tópicos acima, missão cumprida 🥑
🙏 Créditos
- AbacatePay — gateway de pagamentos, API e produto. Esta biblioteca apenas consome a API REST pública deles, documentada em https://docs.abacatepay.com.
- Comunidade Python brasileira por inspirar projetos open-source de qualidade.
Esta biblioteca não é afiliada à AbacatePay. AbacatePay é marca registrada de seus respectivos titulares.
Release files for abacapython 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| abacapython-0.1.0.tar.gz | 29.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| abacapython-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 69.4 kB
Release files / abacapython-0.1.0.tar.gz
| Download URL | abacapython-0.1.0.tar.gz |
|---|---|
| Size | 29.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c1b739ef9b5960b408ebe2ed6f089612c17ea9855748f97710bc0f41f5c1bd11
|
|
BLAKE2b-256 checksum How to use checksums |
9869b211e656cf3c2687eb20ea3318ed32b5cc1348cf88d78abb166c7b206cf1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / abacapython-0.1.0-py3-none-any.whl
| Download URL | abacapython-0.1.0-py3-none-any.whl |
|---|---|
| Size | 39.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
995ba4005bf051b5722f9dc8d28d2ed4e53d97a32f42223c2ac7c358a50ec04a
|
|
BLAKE2b-256 checksum How to use checksums |
3fcbfceb51d89fbbae02bcadbee502f7855658abc52953247fc654d86f441429
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|