PagoTIC SDK para Python
Paquete no oficial. Este SDK es mantenido por la comunidad y no está afiliado, respaldado ni soportado por PagoTIC. Usá la API oficial bajo tu propia responsabilidad.
SDK en Python para integrar la pasarela de pagos PagoTIC (Pay per TIC). Incluye cliente sincrónico y asincrónico, autenticación OAuth2 automática, modelos tipados con Pydantic, pagos, distribución programada, importación masiva, suscripciones y utilidades para webhooks.
- Python 3.10+
httpx+pydanticv2- Tipado completo (
py.typed) - Tests con
respx, lint conruff, chequeo de tipos conmypy
Instalación
pip install pagotic-sdk
Con pipx para instalarlo aislado:
pipx install pagotic-sdk
Para generar códigos QR localmente (sin servicios externos) agregá el extra qr:
pip install "pagotic-sdk[qr]"
pipx install "pagotic-sdk[qr]" # alternativa con pipx
Con Poetry:
poetry add pagotic-sdk
poetry add "pagotic-sdk[qr]" # opcional, para QR local
También podés instalarlo desde el repositorio:
pip install "pagotic-sdk @ git+https://github.com/Alitux/pagotic-sdk.git"
Inicio rápido
from pagotic import PagoTIC
with PagoTIC() as sdk:
payment = sdk.payments.create(
{
"external_transaction_id": "orden-123",
"currency_id": "ARS",
"details": [
{
"external_reference": "item-1",
"concept_id": 920,
"concept_description": "Suscripción mensual",
"amount": 1500.50,
}
],
"payer": {
"name": "Ana Pérez",
"email": "ana@example.com",
"identification": {
"type": "DNI_ARG",
"number": "12345678",
"country": "ARG",
},
},
"notification_url": "https://example.com/webhooks/pagotic",
}
)
print(payment.id, payment.status, payment.form_url)
Configuración
Las credenciales se pueden pasar al constructor o definir por entorno:
| Variable | Descripción |
|---|---|
PAGOTIC_USERNAME |
Usuario de la API |
PAGOTIC_PASSWORD |
Contraseña |
PAGOTIC_CLIENT_ID |
Client ID de Keycloak |
PAGOTIC_CLIENT_SECRET |
Client Secret de Keycloak |
PAGOTIC_AUTH_URL |
Default: https://a.paypertic.com |
PAGOTIC_API_URL |
Default: https://api.paypertic.com |
PAGOTIC_REALM |
Default: entidades |
PAGOTIC_TIMEOUT |
Timeout HTTP en segundos (default: 30) |
PAGOTIC_MAX_RETRIES |
Reintentos en GET/HEAD (default: 2) |
PAGOTIC_RETRY_BACKOFF |
Base del backoff exponencial (default: 0.25) |
PAGOTIC_TOKEN_LEEWAY |
Margen de renovación del token (default: 30) |
Las credenciales y URLs se normalizan automáticamente: se ignoran los espacios
al inicio y al final, y un valor con solo espacios se considera ausente. En los
ejemplos y tests de integración el .env se carga con override=True para que
variables del sistema (por ejemplo USERNAME) no pisen las credenciales.
from pagotic import PagoTIC
sdk = PagoTIC(
username="...",
password="...",
client_id="...",
client_secret="...",
)
El token se solicita de forma lazy, se cachea según expires_in, se renueva
con refresh_token y, ante un 401, se reintenta una vez. Los reintentos por
red o 5xx/429 solo aplican a métodos idempotentes (GET/HEAD), nunca a la
creación de pagos.
Pagos
Crear, obtener y cancelar
payment = sdk.payments.create({...})
same = sdk.payments.get(payment.id)
sdk.payments.cancel(payment.id, "Solicitado por el comercio")
sdk.payments.cancel_objection(payment.id, "Objeción resuelta")
Listar con filtros
result = sdk.payments.list(
page=1,
limit=20,
sorts={"request_date": "descending"},
filters=[
{"field": "collector_id", "operation": "EQUAL", "value": "123"},
{
"field": "request_date",
"operation": "GREATER_THAN_OR_EQUAL_TO",
"value": "20250101T000000000-0300",
},
],
)
La API exige combinaciones mínimas de filtros (por ejemplo
collector_id + request_date). No uses BETWEEN: enviá dos filtros sobre el
mismo campo. Para fechas podés usar format_filter_datetime.
Búsqueda legacy
sdk.payments.search({"payer_email": "ana@example.com", "status": "approved"})
Devoluciones, agrupaciones y cupones
refund = sdk.payments.refund(payment.id, {"reason": "Reintegro"})
grouped = sdk.payments.group([payment_a.id, payment_b.id])
sdk.payments.cancel_group(grouped.id, "Cancelación de la agrupación")
coupon = sdk.payments.create_coupon(payment, media_payment_id=97) # 97 Rapipago, 98 Pago Fácil
print(coupon.payment_methods[0].coupon_number)
Medios de pago y presets
MediaPayment enumera los media_payment_id documentados. Podés combinar
tarjetas de crédito, débito y QR en el checkout con presets:
from pagotic import MediaPayment, PaymentRequest, Presets
payment = sdk.payments.create(
PaymentRequest(
external_transaction_id="orden-125",
currency_id="ARS",
details=[{"external_reference": "a", "amount": 1500}],
payer={"name": "Ana Pérez", "email": "ana@example.com"},
presets=Presets(
media_payment_ids=[
*MediaPayment.cards(), # crédito + débito
MediaPayment.QR,
]
),
)
)
print(payment.form_url) # checkout filtrado a esos medios
presets solo filtra las opciones del checkout: no cobra en el momento. Para
habilitar el QR interoperable usá MediaPayment.QR (85). También podés agrupar
por tipo: MediaPayment.credit_cards(), MediaPayment.debit_cards(),
MediaPayment.cards() y MediaPayment.coupons().
Cuando se cobra directo con tarjeta (type="online" + payment_methods), el
QR no participa del flujo. Los IDs deben estar habilitados para el comercio.
QR
El pago se crea con QR como medio (por ejemplo, presets con
MediaPayment.QR). Una vez creado, raw_qr aparece en payment_methods[] al
consultar sdk.payments.get(id) o en el webhook:
from pagotic import save_qr
payment = sdk.payments.get(payment_id)
if payment.raw_qr:
path = save_qr(payment.raw_qr, "qr.png", scale=6)
print(f"QR guardado en {path}")
El QR se genera localmente con segno (Python
puro, sin Pillow ni servicios externos). Para eso instalá el extra:
pip install "pagotic-sdk[qr]"
También están render_qr_png y render_qr_svg para obtener los bytes o el SVG
en memoria. Si preferís delegar la imagen a un servicio externo, seguí usando
build_qr_image_url.
Cada QR es de un solo uso: una vez pagado queda invalidado.
Distribución programada
Al crear un pago se puede repartir el monto entre varias cuentas CBU:
from pagotic import Distribution, PaymentRequest
payment = sdk.payments.create(
PaymentRequest(
external_transaction_id="orden-124",
currency_id="ARS",
details=[
{"external_reference": "a", "amount": 800},
{"external_reference": "b", "amount": 200},
],
payer={"name": "Ana Pérez", "email": "ana@example.com"},
distribution=Distribution.scheduled(
[
{
"cbu": "0000000000000000000000",
"cuit": "20123456789",
"name": "Proveedor A",
"amount": 800,
},
{
"cbu": "1111111111111111111111",
"cuit": "20987654321",
"name": "Proveedor B",
"amount": 200,
},
]
),
)
)
Validación obligatoria: la suma de distribution.details[].amount debe ser
exactamente igual a la suma de details[].amount. Si no coincide, el SDK lanza
PagoTICValidationError y no envía la request.
Importación masiva
El CSV debe estar sin encabezados y tener como máximo 40.000 registros. Al menos
uno de los flags debe ser true; si match_identification=True, los otros dos
deben ser false.
summary = sdk.imports.preimport("pagos.csv", match_payer=True)
sdk.imports.get(summary.import_id)
details = sdk.imports.details(summary.import_id)
sdk.imports.approve(summary.import_id)
# o bien:
sdk.imports.cancel(summary.import_id, "Importación duplicada")
También están disponibles las rutas legacy verify_legacy, approve_legacy y
cancel_legacy.
Suscripciones (experimental)
Esta funcionalidad solo aparece en la colección Postman, no en la documentación PDF. La API podría cambiarla sin previo aviso.
subscription = sdk.subscriptions.create(
{
"currency_id": "ARS",
"due_day": "30",
"recurrence": "monthly",
"detail": {
"external_reference": "plan-1",
"concept_description": "Plan mensual",
"amount": 5000,
},
"payment_method": {
"number": "4111111111111111",
"holder": {
"name": "Ana Pérez",
"identification": {"type": "DNI_ARG", "number": "12345678", "country": "ARG"},
},
},
"payer": {"name": "Ana Pérez", "email": "ana@example.com"},
}
)
sdk.subscriptions.list()
sdk.subscriptions.search({"payer_email": "ana@example.com"})
sdk.subscriptions.cancel(subscription.id, "Baja solicitada")
Webhooks
PagoTIC envía el JSON del pago a notification_url. La documentación no define
firma ni secreto, así que el SDK solo parsea el payload:
from fastapi import FastAPI, Request
from pagotic import parse_notification
app = FastAPI()
@app.post("/webhooks/pagotic")
async def pagotic_webhook(request: Request):
payment = parse_notification(await request.body())
if payment.status == "approved":
...
return {"ok": True}
Errores
from pagotic import (
PagoTICAPIError,
PagoTICAuthError,
PagoTICConnectionError,
PagoTICValidationError,
)
try:
sdk.payments.get("no-existe")
except PagoTICAPIError as exc:
print(exc.status_code, exc.code, exc.extended_code, exc.message, exc.payload)
Jerarquía: PagoTICError → PagoTICConfigError, PagoTICValidationError,
PagoTICConnectionError, PagoTICAPIError, PagoTICAuthError.
Cliente asincrónico
from pagotic import AsyncPagoTIC
async with AsyncPagoTIC() as sdk:
payment = await sdk.payments.create({...})
await sdk.payments.cancel(payment.id, "Cancelado")
Desarrollo
poetry install
make lint # ruff check + format --check
make typecheck # mypy
make test # pytest
make test-cov # pytest + cobertura
make build # wheel + sdist
Los tests unitarios usan respx y no tocan la red. Los tests de integración
están marcados con integration y se saltean si no hay credenciales:
cp .env.example .env # completá tus credenciales
PAGOTIC_RUN_INTEGRATION=1 poetry run pytest -m integration
.env está ignorado por git; nunca commitees credenciales.
Mantenimiento
Mantenido por Alitux — alitux@disroot.org.
Licencia
GNU General Public License v3.0 o posterior. Ver LICENSE.
Metadata
Release files for pagotic-sdk 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pagotic_sdk-0.1.1.tar.gz | 39.4 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pagotic_sdk-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.9 kB
Release files / pagotic_sdk-0.1.1.tar.gz
| Download URL | pagotic_sdk-0.1.1.tar.gz |
|---|---|
| Size | 39.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1ac69bd2e1c061ceedda5758c38376fa9b0e85b6a12398cf46da9f32f699f7c9
|
|
BLAKE2b-256 checksum How to use checksums |
fb6912e8d9c8e6a12102c6a948ee8599c43aec17c923b3896b95ea63aab0978e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / pagotic_sdk-0.1.1-py3-none-any.whl
| Download URL | pagotic_sdk-0.1.1-py3-none-any.whl |
|---|---|
| Size | 43.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
503659d24f06375b3e908feeb86316cf92c800f83ae7de161e72f27ac37a5ce1
|
|
BLAKE2b-256 checksum How to use checksums |
a4860c97dde59ce01fc3989f98a7b001ba0a82c2bc0590596649fcfd994fb18b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logSecurity for pagotic-sdk 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pagotic_sdk-0.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.