Funciones por integración
Devoluciones y avisos por WhatsApp: qué podés usar, cómo se piden y qué elegís vos.
Dos funciones se configuran por integración:
| Función | Cómo la activás | Qué elegís vos, en Configuración |
|---|---|---|
| Avisos por WhatsApp | Ya vienen activos (Chytapay puede limitarlos) | Si sale el aviso del cobro |
| Devoluciones | Pedilas a contacto@chytapay. |
Qué devoluciones automáticas corren |
Cómo se activan
Se configuran en Producción. Lo que tu integración no tiene aparece bloqueado, con un botón para pedirlo. El Portal no tiene un botón para devolver un cobro: eso lo hacés por API, o lo hace soporte de Chytapay.
Devoluciones
La plata vuelve a la cuenta desde la que se pagó. Pedí los modos que vayas a usar:
| Modo | Qué hace |
|---|---|
| Por API | Devolvés un cobro, total o parcial, con el endpoint de devoluciones. |
| Automática por excedente | Si el pagador transfiere de más, devolvemos la diferencia (desde $1). |
| Automática por pago de menos | Si el pagador transfiere menos del total, devolvemos el pago entero. Llega payment. con motivo partial_. |
| Automática sin asignar | Si una transferencia no corresponde a ningún cobro, la devolvemos. |
Devolver por API
Necesitás dos cosas: el modo por API en tu integración y la autorización del comercio. Mandá la autorización escrita del comercio a [email protected] o por WhatsApp al +54 9 351 543 0077. Hasta entonces el endpoint responde 403 RefundsNotConsentedError. Se devuelven pagos de los últimos 10 días. Con el id_token del comercio:
cURL
curl -X POST https://integration-api.test.chytapay.com.ar/payment-request/pedido-1001/refunds \
-H "Authorization: Bearer $ID_TOKEN" \
-H "Idempotency-Key: devolucion-pedido-1001-a" \
-H "Content-Type: application/json" \
-d '{ "amount": 5000, "reason": "Producto sin stock" }'Respuesta
{
"refundId": "00000000-0000-0000-0000-000000000000",
"paymentRequest": { "referenceId": "pedido-1001", "state": "total_payment" },
"origin": "api",
"trigger": null,
"status": "pending",
"requestedAmount": 5000,
"refundedAmount": 0,
"reason": "Producto sin stock",
"items": [{ "amount": 5000, "status": "pending" }]
}Responde 202: la devolución es asincrónica y el resultado llega por webhook.
| Campo | ¿Obligatorio? | Qué es |
|---|---|---|
Idempotency- (header) |
Sí | De 1 a 255 caracteres. Un reintento con la misma clave y el mismo cuerpo devuelve la misma devolución. |
amount |
No | Pesos, mayor a 0, hasta 2 decimales. Sin él, se devuelve todo lo que queda de los pagos de los últimos 10 días. Con él, esa parte, del pago más nuevo al más viejo. |
reason |
No | Hasta 500 caracteres. |
Podés hacer devoluciones parciales una tras otra hasta el total, de a una por vez. Para consultar una devolución, GET /refunds/{refundId} (incluye las automáticas).
status es pending, processing, succeeded, failed o partially_failed. Un cobro devuelto pasa a refunded o partially_refunded.
Ver los errores de devoluciones
Los mensajes de la API están en inglés.
| Status | Error | Cuándo |
|---|---|---|
| 400 | Idempotency |
Falta el header Idempotency- o tiene más de 255 caracteres. |
| 403 | Refunds |
Tu integración no tiene devoluciones. Pedilas. |
| 403 | Api |
Tu integración no tiene el modo por API. Pedilo. |
| 403 | Refunds |
Falta la autorización del comercio para devolver por API. |
| 404 | Payment |
No hay un cobro con ese referenceId en tu integración. |
| 409 | Refund, RefundIn |
Ya está devuelto, o tiene una devolución en curso. |
| 409 | RefundNo, Refund |
No hay pagos para devolver, o ninguno en los últimos 10 días. |
| 409 | Refund, Refund |
Un pago todavía no llegó a la cuenta principal del comercio, o no tiene cuenta de origen. |
| 409 | Refund |
El cobro está facturado: pedí la devolución a soporte. |
| 409 | Refund |
El comercio no tiene saldo para la devolución. |
| 409 | Idempotency |
Otra solicitud con la misma clave sigue en curso. |
| 422 | Refund |
El monto supera lo que queda por devolver. |
| 422 | Idempotency |
La clave ya se usó con otro cuerpo. |
| 503 | Principal |
No pudimos consultar el saldo. No se creó nada: reintentá con la misma clave. |
Devoluciones automáticas
Elegís cuáles corren en Configuración, Devoluciones. Un modo recién activado arranca prendido, salvo que ya hayas elegido sobre él: desde ese momento, las transferencias que cumplan la condición se devuelven solas. No necesitan la autorización del comercio.
No corren si el comercio tiene más de una integración activa y la transferencia no se asignó a un cobro.
Eventos de devolución
refund.succeeded (toda la plata volvió al pagador) y refund.failed (al menos una parte no se pudo devolver) vienen apagados. Activalos en Webhooks, pestaña Eventos. Llegan a las mismas URLs que el resto, con la misma firma.
Ejemplo de refund.succeeded:
{
"event": "refund.succeeded",
"livemode": false,
"refundId": "00000000-0000-0000-0000-000000000000",
"paymentRequest": { "referenceId": "pedido-1001", "state": "partially_refunded" },
"origin": "api",
"trigger": null,
"status": "succeeded",
"requestedAmount": 5000,
"refundedAmount": 5000,
"reason": "Producto sin stock",
"items": [{ "amount": 5000, "status": "succeeded" }],
"merchantUserId": "00000000-0000-4000-8000-000000000001",
"merchantTaxId": "30712345671",
"merchantName": "Comercio de Prueba"
}origindice quién la pidió:api,merchant,chyta(soporte) oauto.triggersolo viaja conauto:unmatched,partialoexcess.paymentRequestesnullen la devolución automática de una transferencia que no se asignó a ningún cobro.reasonesnullen las devoluciones que pide soporte.tenantKeyviaja solo si el comercio está en una sede.
Avisos por WhatsApp
Son mensajes de Chytapay al pagador:
| Mensaje | Qué manda |
|---|---|
| Aviso del cobro | El link de pago por WhatsApp al crear el cobro, y sus recordatorios. Solo sale si el cobro tiene monto y customer.. |
| Confirmación de pago | Avisa al pagador cuando el pago se acredita. |
Qué arranca activado
Por defecto sale la confirmación de pago. El aviso del cobro arranca apagado: lo prendés vos en Configuración, Avisos por WhatsApp, y recién entonces rige.
Lo que elegís ahí vale cuando el cobro no dice nada. Lo que el cobro manda gana:
sendWhatsappNotificationomitido usa tu elección.trueofalseen el cobro la pisa.sendWhatsappPaymentConfirmationomitido conserva el comportamiento de cada modo de conciliación. Está en confirmación de pago.
Si un cobro pide un mensaje que tu integración no tiene, la API responde 403 (WhatsappNotEnabledError, WhatsappNotificationNotAllowedError o WhatsappPaymentConfirmationNotAllowedError). Escribinos para activarlo. El tope diario de mensajes sigue rigiendo.