Catalog PyPI
PACKAGE EXPLORERView in registry

abacapython

PyPI

SDK Python não-oficial para AbacatePay (PIX, Checkout, Assinaturas, Webhooks) — projeto educacional. Já existe um SDK oficial; use o oficial em produção.

abacapythonabacatepaybrazilcheckoutfintechgatewaypaymentspixsubscriptions
Versions collected1
Direct dependencies12From release 0.1.0
Last observed20 Oct, 17:08 UTC

README

Version 0.1.0 documentation

🥑 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âmetroDefaultDescrição
api_keyos.environ["ABACATEPAY_API_KEY"]Bearer Token da AbacatePay.
base_urlhttps://api.abacatepay.com/v2Pode ser sobrescrito por ABACATEPAY_BASE_URL.
timeout30.0Timeout (s) para cada requisição.
max_retries2Tentativas extras para 429, 5xx, timeouts e erros de conexão.
backoff_factor0.5Fator base do backoff exponencial entre retries.
backoff_max8.0Limite (s) para qualquer espera entre retries.
http_clientNoneInstância customizada de httpx.Client / httpx.AsyncClient.

🗺️ Mapa de endpoints

Recurso na APIAcesso 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

PythonStatus
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 (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 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.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.019 May 202612

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
nicollasrezende/abacapython

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 17:08 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:e7452338685513f7b85c4db0d569501ffbdc2c615c94adec75c6ea83a43ff3e4