Saltar al contenido
ESENIr al Portal

Operación y errores

Ambientes, checklist de paso a producción, límites de uso, errores por endpoint y descargas de la Integration API.

Los datos para operar la integración: ambientes, límites, errores y descargas.

Ambientes y URLs

Tu integración tiene dos ambientes, Sandbox y Producción, con credenciales propias. Los dos se manejan desde el mismo portal, chytapay.com.ar/portal/login, con el selector de ambiente.

Servicio Sandbox Producción
Integration API (cobros, bulk, payer-lookup) https://integration-api.test.chytapay.com.ar https://integration-api.chytapay.com.ar
Auth API (OAuth: /integration/oauth2/*) https://auth-api.test.chytapay.com.ar https://auth-api.chytapay.com.ar
Clave publicable del widget pk_test pk_live

La Integration API monta sus rutas en la raíz: /payment-request, /payment-request/bulk y /payer-lookup. El widget usa /v1/payments en el mismo host.

Los tokens de prueba, el webhook de prueba y la simulación de pago existen solo en Sandbox. En Producción, livemode es true solo con un pago real.

Paso a producción

Producción se pide en Credenciales: si el chequeo automático lo aprueba, generás las credenciales de producción con el selector de ambiente en Producción, y si no, el pedido pasa a revisión. Nada de Sandbox se copia solo. Antes de cobrar, revisá:

  1. Credenciales. Generalas en Credenciales y usá el clientId y el clientSecret de producción contra auth-api.chytapay.com.ar, y la pk_live si usás el widget (la sk_live, solo si creás cobros por /v1/payments).
  2. Comercios vinculados. Los vínculos de Sandbox no existen en producción: cada comercio repite el OAuth de Conectar comercios.
  3. Webhooks. Cargá la URL en Configuración con el ambiente en Producción, verificá la firma con el secreto de producción y activá payment.unmatched si lo necesitás, porque es opt-in. Consultá las garantías de entrega y la suscripción.
  4. Errores. Resolvé el 409, el 429 y los timeouts con la tabla de reintentos.
  5. Tokens y eventos. Renová el idToken de cada comercio con el refreshToken antes de la hora, deduplicá por X-Chytapay-Webhook-Id y respondé 2xx en menos de 5 segundos.

Reintentos de tu lado

No hay idempotency key. Lo que evita un cobro duplicado es el referenceId, único por integración y cuenta de comercio, cancelados incluidos.

Situación Qué hacer
Timeout o 5xx en un create GET /payment-request/{referenceId}: con 404, reintentá con el mismo referenceId.
409 ReferenceIdAlreadyExists Ya se creó. Consultalo con GET; no generes otro referenceId.
429 en create o bulk No reintentes en loop: esperá hasta las 00:00 hora Argentina. Un bulk que no entra entero en el tope no crea nada.
Timeout o 5xx en un bulk Consultá con GET un referenceId del lote: el bulk es todo o nada.
422 en un bulk reintentado Si el motivo es The referenceId already exists for this integration, el lote anterior se creó.
503 en payer-lookup ARCA no respondió. Reintentá, o seguí sin validar al pagador.

El ejemplo de create con timeout y 409 está en Crear cobros.

Límites

El único tope diario al crear cobros es el de mensajes de WhatsApp. No hay tope de requests ni de cobros creados por día. Se reinicia a las 00:00 hora Argentina (UTC-3).

Tope Valor Al superarlo
Mensajes de tu integración Por integración, sumados todos sus comercios: 20 por día en Sandbox y 200 iniciales por día en Producción. Se amplía con Pedir más límite, en la pantalla de inicio del Portal. 429 IntegrationDailyRequestLimitExceededError
Mensajes compartidos entre integraciones Un tope global diario 429 IntegrationGlobalDailyMessageLimitExceededError

Qué cuenta como mensaje de WhatsApp

Cada cobro creado con sendWhatsappNotification: true cuenta como un mensaje. Los cobros que no piden notificación por WhatsApp no consumen el tope. Un bulk que no entra entero en el tope no crea nada.

La respuesta 429 de los topes de mensajes

El cuerpo trae code (cuál de los dos topes) y message. El tope de tu integración suma availableAt (el reinicio, en hora argentina), maxRequestsPerDay y maxMessagesPerDay. El global suma requestedMessages y availableAtUnixSeconds (el reinicio, en segundos Unix). Si no se puede chequear el tope, el create y el bulk responden 503 IntegrationDailyLimitUnavailableError: reintentá en unos minutos. El reset es a las 00:00 hora Argentina: no reintentes en loop, esperá hasta entonces. Con creates en paralelo cerca del tope, un cobro puede quedar creado aunque responda 429: confirmá con GET antes de recrearlo.

Otros límites

Límite Valor Al superarlo
Items por bulk 1 a 100 por llamada 400 ValidationError
Pool de CVUs, por cuenta de comercio Hasta 100 por cuenta de comercio 400 InsufficientActiveAccountsError

Payer-lookup

GET /payer-lookup?document= tiene su propia cuota, separada de los topes de creación: 1000 unidades por día, por integración y cuenta de comercio, que se reinician a las 00:00 hora Argentina. Un CUIL o CUIT cuesta 1 y un DNI cuesta 2, porque Chytapay consulta a ARCA los dos CUIL posibles. Al superarla, 429 PayerLookupDailyLimitExceededError.

  • No consumen: el 400 por document inválido y el 503 que se responde sin consultar a ARCA.
  • Sí consumen: el 200 con name: null y el 503 porque ARCA no respondió.
  • El 429 trae code, message, availableAtUnixSeconds (el reset, en segundos Unix) y maxLookupsPerDay (1000).

Consultá cómo validar al pagador.

Pool de CVUs

El pool es de la cuenta de comercio, lo comparten todas sus integraciones y lo ocupan los CVUs de los cobros abiertos. Si no hay un CVU libre, el create y el bulk dan 400 InsufficientActiveAccountsError y no crean nada. Al cerrarse un cobro, su CVU vuelve al pool. Consultá cómo afecta a cada modo en Conciliación.

Errores por endpoint

Decidí por el status HTTP y después por code o error, nunca por el texto de message. Las tablas siguen el spec OpenAPI.

Ver las formas del cuerpo de error

Formato del cuerpo de error

No hay header de request id. El id viene en el cuerpo, solo en la forma general: guardalo en tus logs. La mayoría de los mensajes están en inglés.

Forma del cuerpo Cuándo
{ code, message, id } Forma general: 400 de negocio, 409 CustomerAlreadyAssociatedError, 500
{ code, message, id, validationDetails } 400 ValidationError. validationDetails es una lista de { field, message }; message repite el primero.
{ error, message, referenceId } 409 del create
{ message, errors } 422 del bulk. errors es una lista de { index, referenceId, reason }.
{ error, message, data } 409 del PATCH, del PATCH del pagador y del cancel
{ message } 404 de cobro inexistente, de integración no lista para cobrar y de sede
{ code, message } 503 de payer-lookup
Texto plano, no JSON 400, 403 y 404 del chequeo del token

Comunes a todos los endpoints

HTTP Cuerpo Cuándo pasa y qué hacer
401 Token faltante, inválido o vencido. Renovalo con el refresh token de Conectar comercios.
400 Bad request: Missing required authentication data El token no trae la cuenta, el rol o la aplicación. Mandá el id_token del comercio en Authorization: Bearer.
404 Integration client not found El token es de otra aplicación. Pedilo con el clientId de tu integración en ese ambiente.
403 Not authorized as user of integration client La cuenta de comercio no está vinculada, o se desvinculó. Vinculala con el OAuth.
500 { code, message, id } Error interno. En un create o bulk, consultá con GET antes de reintentar.

Crear un cobro: POST /payment-request

HTTP code o error Cuándo pasa y qué hacer
400 ValidationError Falta un campo, tiene tipo o rango inválido, o ese type no lo acepta. Mirá validationDetails.
400 WebhookUrlBlockedError webhookUrl apunta a una dirección interna o privada.
400 InsufficientActiveAccountsError No hay CVU libre en el pool del comercio.
409 ReferenceIdAlreadyExists El referenceId ya existe, aunque el cobro esté cancelado. No trae el cobro: consultalo con GET.
409 CustomerAlreadyAssociatedError Chocaron dos creates simultáneos para el mismo pagador. Consultá con GET y reintentá si no existe.
429 IntegrationDailyRequestLimitExceededError o IntegrationGlobalDailyMessageLimitExceededError Llegaste al tope de mensajes de WhatsApp. Consultá los límites.

Crear cobros en lote: POST /payment-request/bulk

Si el bulk falla, no se crea ningún cobro del lote.

HTTP code Cuándo pasa y qué hacer
400 ValidationError Lote vacío o de más de 100 items, un item fuera de contrato, o un vencimiento con hora (solo acepta YYYY-MM-DD). Mirá validationDetails.
400 InsufficientActiveAccountsError El pool del comercio no alcanza para el lote.
404 La integración no está lista para cobrar y reintentar no lo resuelve. Escribí a soporte.
422 Items que no pasan la validación de negocio, todos en errors. Corregilos y reenviá el lote completo.
429 IntegrationDailyRequestLimitExceededError o IntegrationGlobalDailyMessageLimitExceededError El lote no entra entero en el tope de mensajes de WhatsApp: no se crea nada.

Los reason del 422 son Duplicate referenceId within the batch, The referenceId already exists for this integration, The taxDocument does not resolve to a valid CUIL y Duplicate payer within the batch (el mismo documento en más de un item).

Consultar un cobro: GET /payment-request/{referenceId}

HTTP Cuerpo Cuándo pasa y qué hacer
404 { "message": "Payment request not found" } No hay cobro con ese referenceId para esta integración y cuenta de comercio. Revisá que el token sea del comercio correcto.

Completar el monto: PATCH /payment-request/{referenceId}

HTTP code o error Cuándo pasa y qué hacer
400 ValidationError amount falta, no es positivo, tiene más de 2 decimales o supera 200.000.000.
404 No existe el cobro.
409 PaymentRequestCannotBeModified El cobro no está en draft, o ya recibió pagos: solo un borrador sin pagos acepta PATCH.

Corregir el pagador: PATCH /payment-request/{referenceId}/customer

HTTP code o error Cuándo pasa y qué hacer
400 ValidationError taxDocument falta o es inválido (formato o dígito verificador), o name, email o phoneNumber están fuera de contrato.
404 No existe el cobro, o la integración no está lista para cobrar.
409 PaymentRequestCustomerCannotBeModified No se puede cambiar el pagador. El motivo está en data.reason.
Ver los valores de data.reason
data.reason Qué significa
conciliation_type_not_cuil El cobro es de modo CVU, que no guarda el documento del pagador.
state_not_modifiable El cobro está en un estado final.
payment_already_received El cobro ya recibió plata.
no_collision_free_account Ningún CVU puede alojar el documento nuevo. No se cambió nada.
missing_notification_contact Al pagador nuevo le falta el contacto que piden los recordatorios.
incomplete_payment_request_data El cobro no tiene pagador asociado.
concurrent_modification Otro cambio en paralelo. Releé el cobro y reintentá.

Consultá cuándo usarlo en corregir el pagador.

Cancelar un cobro: POST /payment-request/{referenceId}/cancel

HTTP error Cuándo pasa y qué hacer
404 No existe el cobro.
409 PaymentRequestCannotBeCanceled El cobro no está en draft ni en pending: tiene pagos parciales, está pagado, vencido o cancelado.

Validar un documento: GET /payer-lookup

HTTP code Cuándo pasa y qué hacer
200 con name: null ARCA respondió y el documento no tiene titular. Pedile al pagador que lo revise.
400 ValidationError document no es un CUIL o CUIT de 11 dígitos ni un DNI de 7 u 8.
404 La cuenta no está vinculada.
429 PayerLookupDailyLimitExceededError Llegaste a las 1000 unidades del día.
503 PayerLookupProviderUnavailableError No se pudo consultar a ARCA: el pagador no quedó verificado. Reintentá, o seguí sin validar.
503 PayerLookupQuotaUnavailableError No se pudo chequear la cuota. Reintentá.

Asignar la sede: PUT /my-integration/tenant

HTTP Cuerpo Cuándo pasa y qué hacer
400 ValidationError Falta tenantKey o está vacío.
404 { "message": "The specified tenant does not exist or was deleted" } La sede no existe, se borró o es de otra integración. Consultá Sedes.
404 { "message": "No integration account was found for the authenticated user" } La cuenta de comercio no está vinculada.

OAuth

Los errores de authorize, token, refresh y revoke están en Conectar comercios.

Errores típicos

  • Usar el token equivocado. La Integration API recibe el id_token de la cuenta de comercio, no el del admin de la integración ni el clientSecret.
  • Recrear tras un timeout o reintentar un 429 en loop. Consultá reintentos y la respuesta 429.
  • Leer name: null como falla de ARCA. El documento no tiene titular; la falla es el 503.

Descargas

OpenAPI

Importá el spec en Postman, Insomnia, Bruno o cualquier cliente de API, o navegá la API Reference:

  • Integration API: https://public-api.chytapay.com.ar/integration-api-swagger
  • Auth API: https://public-api.chytapay.com.ar/auth-api-swagger

El spec todavía declara 10.000.000 como tope de monto en el PATCH; la API aplica 200.000.000.

Colección Postman

Trae un environment de Sandbox (el archivo se llama Test) y otro de Producción, con los hosts cargados. Trae todos los endpoints de cobros, el payer-lookup y la corrección del pagador, con fechas de ejemplo que siempre quedan en el futuro.

  • Colección: /api/assets/postman/Chytapay-Integration-API.postman_collection.json
  • Environment de test: /api/assets/postman/Chytapay-Test.postman_environment.json
  • Environment de producción: /api/assets/postman/Chytapay-Production.postman_environment.json

Preguntas frecuentes

¿El límite y el pool son por comercio o por integración?

El tope de mensajes, por integración (suma todos sus comercios). La cuota del payer-lookup, por integración y cuenta de comercio. El pool de CVUs, por cuenta de comercio. Más respuestas en Preguntas frecuentes.