Skip to main content

🥑 abacapython

SDK Python não-oficial para o gateway de pagamentos AbacatePay

PyPI Python License: MIT CI Code style: ruff

📚 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 (AbacaPay e AsyncAbacaPay, ambos sobre httpx)
  • 🧱 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 429 e 5xx
  • 🔐 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)
  • httpx com retries + backoff exponencial + jitter
  • Pydantic v2 com alias (camelCasesnake_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 mkdocstrings gerando 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)

Source distribution for abacapython 0.1.0
File Size Uploaded
abacapython-0.1.0.tar.gz 29.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for abacapython 0.1.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page