Convenciones
Base URL
https://api.pay.ingalca.comTodos los endpoints viven bajo /v1/. La URL es la misma para test y live; el entorno lo define la API key (ver entornos).
Estructura de respuesta
Éxito:
{ "data": { ... }}Listado:
{ "data": [...], "meta": { "next_cursor": "eyJpZCI6MTIzfQ", "prev_cursor": null, "per_page": 25 }}Error:
{ "error": { "code": "VALIDATION_FAILED", "message": "...", "details": { /* opcional */ } }}IDs públicos
Cada recurso tiene un ID público con prefijo:
| Recurso | Prefijo | Ejemplo |
|---|---|---|
| Payment | pay_ | pay_abc123def456 |
| Card | card_ | card_xyz789abc012 |
| Customer | cust_ | cust_qrs456tuv789 |
| Webhook | evt_ | evt_a1b2c3d4e5f6 |
Los IDs no son enumerables (random base32-like). Asumí que pueden cambiar de longitud en el futuro — no los parsees.
Paginación
Todos los listados usan cursor pagination. NO hay ?page=N.
GET /v1/payments?cursor=eyJpZCI6MTIzfQ&per_page=50La respuesta trae meta.next_cursor (más resultados) y meta.prev_cursor (página anterior). Si next_cursor es null, llegaste al final.
Filtros
Los listados aceptan filtros como query params. Filtros vacíos se ignoran.
GET /v1/payments?status=confirmed&provider=dinelco&from=2026-05-01&to=2026-05-31Cada endpoint documenta sus filtros disponibles.
Fechas
Todas las fechas en respuestas son ISO 8601 con timezone:
2026-05-02T14:32:11+00:00Para filtros, aceptamos YYYY-MM-DD (interpretado como Paraguay) o ISO 8601 completo.
Montos
Los montos van en enteros representando la unidad mínima de la moneda. Para PYG (sin decimales), el monto es directamente la cantidad de guaraníes:
{ "amount": 150000, "currency": "PYG"}Esto son ₲ 150.000.
Hoy soportamos solo PYG. Si en el futuro agregamos USD, los amount van a ser en centavos (amount: 1000 = $10.00).
Headers comunes
| Header | Para qué |
|---|---|
Authorization | Bearer token (tu API key). Obligatorio en /v1/*. |
Content-Type | application/json para POST/PUT con body JSON. |
Idempotency-Key | (próximamente) clave única para reintentos seguros. |
HTTP status codes
| Code | Significado |
|---|---|
| 200 | OK |
| 201 | Recurso creado |
| 204 | OK sin body |
| 400 | Request mal formado |
| 401 | API key inválida o ausente |
| 403 | API key válida pero sin permisos para esta acción |
| 404 | Recurso no existe (o pertenece a otro tenant) |
| 422 | Validación falló (mirar error.details.fields) |
| 429 | Rate limit superado |
| 500 | Error interno (deberíamos verlo nosotros antes que vos) |
| 502 | Error del provider (Dinelco / Bancard) |
| 503 | Servicio temporalmente no disponible |