Pagos
Un pago (pay_...) es el recurso central de la API de Paytami. Se crea una vez y su status avanza a medida que el cliente completa el flujo de pago — ver el catálogo de estados.
El objeto Payment
{
"id": "pay_8f2c1a9d4e6b7c0a1d2e3f40",
"status": "created",
"currency": "GTQ",
"amount": "15000",
"paytami_fee": "435",
"net_amount": "14565",
"description": "Colegiatura agosto 2026",
"checkout_url": "https://app.paytami.com/api/v1/checkout/pay_8f2c1a9d4e6b7c0a1d2e3f40",
"created_at": "2026-08-28T15:04:00.000Z"
}| Campo | Tipo | Descripción |
|---|---|---|
id | string | Identificador público, prefijo pay_. Estable en el tiempo. |
status | string | Ver el catálogo de estados. |
currency | string | GTQ o USD. |
amount | string | Monto bruto del cobro, entero en unidad mínima (centavos), nunca un number. |
paytami_fee | string | Comisión de Paytami sobre este cobro, misma unidad que amount. |
net_amount | string | Lo que recibe tu comercio: amount - paytami_fee. |
description | string | undefined | Solo presente si se envió al crear el pago. |
checkout_url | string | Página de pago, siempre en el dominio de Paytami. |
created_at | string | ISO 8601 en UTC. |
TIP
checkout_url siempre vive en el dominio de Paytami — es parte del contrato estable de la plataforma.
POST /v1/payments
Crea un cobro.
Autenticación: requerida (Authorization: Bearer sk_...). Headers: Idempotency-Key requerido — ver Idempotencia.
Cuerpo de la petición
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
amount | string | Sí | Entero en unidad mínima, como cadena (p. ej. "15000" = Q150.00). |
currency | string | Sí | GTQ o USD. |
method_type | string | Sí | card o bank_transfer. |
success_url | string | Sí | A dónde regresa el cliente si el pago se completa. |
cancel_url | string | Sí | A dónde regresa el cliente si cancela o falla. |
description | string | No | Hasta 500 caracteres. Visible para el cliente en el checkout. |
customer.email | string | No | Correo del cliente final. |
customer.name | string | No | Nombre del cliente final. |
Ejemplo
curl https://app.paytami.com/api/v1/payments \
-X POST \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: 6e4b6f0a-a5f0-4b9a-9b8b-1a2b3c4d5e6f" \
-H "Content-Type: application/json" \
-d '{
"amount": "15000",
"currency": "GTQ",
"method_type": "card",
"success_url": "https://tu-sitio.com/gracias",
"cancel_url": "https://tu-sitio.com/carrito"
}'const res = await fetch('https://app.paytami.com/api/v1/payments', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAYTAMI_SECRET_KEY}`,
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: '15000',
currency: 'GTQ',
method_type: 'card',
success_url: 'https://tu-sitio.com/gracias',
cancel_url: 'https://tu-sitio.com/carrito'
})
})
const pago = await res.json()Respuesta: 201 Created con el objeto Payment.
Errores posibles: 401 unauthorized, 400 idempotency_key_required, 409 idempotency_key_reused, 400 validation_error, 400 currency_not_supported, 400 method_not_supported, 400 amount_below_minimum, 400 amount_above_maximum.
GET /v1/payments/{id}
Consulta un cobro por su id público.
Autenticación: requerida. Solo devuelve pagos que pertenecen al comercio autenticado — un id de otro comercio responde 404, igual que uno inexistente, para no filtrar qué identificadores existen.
curl https://app.paytami.com/api/v1/payments/pay_8f2c1a9d4e6b7c0a1d2e3f40 \
-H "Authorization: Bearer sk_test_..."Respuesta: 200 OK con el objeto Payment. Errores posibles: 401 unauthorized, 404 unknown_payment.
GET /v1/payments
Lista los cobros del comercio autenticado, más recientes primero.
Autenticación: requerida.
Parámetros de consulta
| Parámetro | Tipo | Descripción |
|---|---|---|
limit | number | Entre 1 y 100. Por omisión, 25. |
starting_after | string | id de un pago; devuelve la página siguiente a partir de ahí. |
status | string | Filtra por un estado exacto. |
curl "https://app.paytami.com/api/v1/payments?limit=10&status=captured" \
-H "Authorization: Bearer sk_test_..."Respuesta
{
"data": [ { "id": "pay_...", "status": "captured", "...": "..." } ],
"has_more": true
}Para la página siguiente, pasa el id del último elemento de data como starting_after.
Paginación por cursor: la lista está ordenada por fecha de creación descendente; usar starting_after en vez de un offset numérico evita que un pago nuevo desplace la página mientras paginas.

