Skip to main content

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

Project description

🥑 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

abacapython-0.1.0.tar.gz (29.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

abacapython-0.1.0-py3-none-any.whl (39.7 kB view details)

Uploaded Python 3

File details

Details for the file abacapython-0.1.0.tar.gz.

File metadata

  • Download URL: abacapython-0.1.0.tar.gz
  • Upload date:
  • Size: 29.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for abacapython-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c1b739ef9b5960b408ebe2ed6f089612c17ea9855748f97710bc0f41f5c1bd11
MD5 c6ee3f842b7b9490ee5e9ffcf4daf887
BLAKE2b-256 9869b211e656cf3c2687eb20ea3318ed32b5cc1348cf88d78abb166c7b206cf1

See more details on using hashes here.

File details

Details for the file abacapython-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: abacapython-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 39.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for abacapython-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 995ba4005bf051b5722f9dc8d28d2ed4e53d97a32f42223c2ac7c358a50ec04a
MD5 082d8b6e4bc10f8d87a829a0cd3add2d
BLAKE2b-256 3fcbfceb51d89fbbae02bcadbee502f7855658abc52953247fc654d86f441429

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page