> Chytapay es una plataforma de cobros por transferencia en Argentina. Esta página es parte de la doc de la Integration API: https://chytapay.com.ar/api/
> Conciliación recomendada: por CUIL. Ambientes: test (https://integration-api.test.chytapay.com.ar) y producción (https://integration-api.chytapay.com.ar).
> Página: "Crear cobros" (https://chytapay.com.ar/api/crear-cobros/), actualizada el 2026-10-22.
> Índice completo para asistentes de IA: https://chytapay.com.ar/llms.txt

# Crear cobros

Cómo crear cobros uno por uno o en bulk, con vencimientos, recargo, estados, avisos al pagador y reintentos seguros.

&#xA;En esta página podés consultar cómo crear, seguir y cancelar cobros, uno por uno o hasta 100 por llamada. Necesitás una cuenta de comercio conectada y su `id_token` en `Authorization: Bearer`: consultá [Conectar comercios](https://chytapay.com.ar/api/conectar-comercios/).

Cómo pasa un cobro de un estado a otro.

- `draft` pasa a `pending` cuando le cargás el monto con PATCH.
- Si ya entró plata y falta menos de $1, el cobro cuenta como `total_payment`; sin pagos sigue abierto.
- `pending` pasa a `total_payment` con un pago total, a `partial_payment` con un pago parcial y a `overdue` si vence sin pagos.
- `partial_payment` pasa a `total_payment` cuando se paga el saldo y a `partial_overdue` si vence antes.
- `draft` y `pending` pasan a `canceled` cuando los cancelás, si no recibieron ningún pago.
- Un cobro con pagos pasa a `partially_refunded` o `refunded` cuando se lo devuelve, en parte o por completo.

## 1. Creá un cobro

&#xA;
Identificás cada cobro con tu `referenceId`, que vuelve en cada respuesta y evento.

En tu backend, creá el cobro en Sandbox:

**cURL**

```bash
curl -X POST https://integration-api.test.chytapay.com.ar/payment-request \
  -H "Authorization: Bearer $ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "referenceId": "factura-1001",
    "amount": 25000,
    "description": "Cuota de octubre",
    "dueDates": ["<FECHA_1>", "<FECHA_2>"],
    "surcharge": { "type": "percentage", "value": 10 },
    "conciliationType": "cuil",
    "sendWhatsappNotification": false,
    "sendEmailNotification": true,
    "customer": {
      "name": "Nombre Apellido",
      "email": "pagador@example.com",
      "taxDocument": "20000000001"
    },
    "metadata": { "orden": "1001" }
  }'
```

**Node**

```js
const BASE = 'https://integration-api.test.chytapay.com.ar';

const res = await fetch(`${BASE}/payment-request`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${idToken}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    referenceId: 'factura-1001',
    amount: 25000,
    description: 'Cuota de octubre',
    dueDates: ['<FECHA_1>', '<FECHA_2>'],
    surcharge: { type: 'percentage', value: 10 },
    conciliationType: 'cuil',
    sendWhatsappNotification: false,
    sendEmailNotification: true,
    customer: {
      name: 'Nombre Apellido',
      email: 'pagador@example.com',
      taxDocument: '20000000001',
    },
    metadata: { orden: '1001' },
  }),
});
const cobro = await res.json(); // 201
```

**Python**

```python
import requests

BASE = "https://integration-api.test.chytapay.com.ar"

res = requests.post(
    f"{BASE}/payment-request",
    headers={"Authorization": f"Bearer {id_token}"},
    json={
        "referenceId": "factura-1001",
        "amount": 25000,
        "description": "Cuota de octubre",
        "dueDates": ["<FECHA_1>", "<FECHA_2>"],
        "surcharge": {"type": "percentage", "value": 10},
        "conciliationType": "cuil",
        "sendWhatsappNotification": False,
        "sendEmailNotification": True,
        "customer": {
            "name": "Nombre Apellido",
            "email": "pagador@example.com",
            "taxDocument": "20000000001",
        },
        "metadata": {"orden": "1001"},
    },
)
cobro = res.json()  # 201
```

**Respuesta**

```json
{
  "type": "standard",
  "paymentRequestId": "<uuid del cobro>",
  "referenceId": "factura-1001",
  "amount": 25000,
  "description": "Cuota de octubre",
  "dueDates": ["<FECHA_1>", "<FECHA_2>"],
  "state": "pending",
  "surcharge": { "type": "percentage", "value": 10 },
  "calculatedAmounts": [
    { "dueDate": "<FECHA_1>", "amount": 25000, "isOriginalAmount": true },
    { "dueDate": "<FECHA_2>", "amount": 27500, "surchargeApplied": 2500 }
  ],
  "sendWhatsappNotification": false,
  "sendEmailNotification": true,
  "metadata": { "orden": "1001" },
  "customer": {
    "name": "Nombre Apellido",
    "email": "pagador@example.com",
    "taxDocument": "20000000001"
  },
  "CVU": "<CVU de 22 dígitos>",
  "bankAccountInfo": {
    "accountHolderName": "<titular de la cuenta de comercio>",
    "accountHolderTaxId": "<CUIT del titular>",
    "bankName": "<banco>"
  }
}
```

Reemplazá `<FECHA_1>` y `<FECHA_2>` por fechas futuras dentro de 35 días (por ejemplo, hoy +7 y +14 días). El ejemplo concilia por CUIL, el modo recomendado: antes, [validá el documento](https://chytapay.com.ar/api/conciliacion/#validar-pagador).

### Qué devuelve

**201** con `paymentRequestId`, `state` (`pending`, o `draft` sin monto), `CVU` y `bankAccountInfo` (adónde transfiere el pagador) y, con monto y 2 fechas, `calculatedAmounts` (cada vencimiento con recargo). No devuelve `conciliationType` ni un `surcharge` de tipo `none`; en modo CVU omite `customer.taxDocument`.

## 2. Consultá un cobro

&#xA;Pedilo con `GET /payment-request/{referenceId}`:

```bash
curl https://integration-api.test.chytapay.com.ar/payment-request/factura-1001 \
  -H "Authorization: Bearer $ID_TOKEN"
```

Devuelve el cobro con `state` actualizado; omite `customer.taxDocument`, `conciliationType` y las fechas de aviso. Si no existe para la cuenta de comercio, da **404**. GET y PATCH devuelven `dueDates` y `calculatedAmounts[].dueDate` como fecha UTC, sin la hora: conservá el vencimiento enviado.

### Qué incluye el listado

`GET /payment-request?startDate=AAAA-MM-DD&endDate=AAAA-MM-DD` lista **cobros abiertos**, con una excepción: también devuelve los checkouts que vencieron o se cancelaron sin pagador. Ambas fechas son opcionales. Los demás cobros pagados, vencidos o cancelados dejan de aparecer: seguí su estado con el GET por `referenceId` o los webhooks. Cada ítem trae `status`, `amount` (`0` en borradores), `dueDate` (primer vencimiento en UTC), `paidAmount`, `createdAt` y `customer` sin `taxDocument`, con `phoneNumber` como string normalizado. `status` usa los estados públicos en inglés: `draft`, `pending`, `partial_payment`, `total_payment`, `overdue`, `partial_overdue`, `canceled`, `refunded` y `partially_refunded`.

## 3. Duplicados y reintentos

No hay idempotency key: el `referenceId` es único por integración y cuenta de comercio, incluidos los cancelados. Repetirlo da **409** y no devuelve el cobro existente:

```json
{
  "error": "ReferenceIdAlreadyExists",
  "message": "The provided reference ID already exists for this client",
  "referenceId": "factura-1001"
}
```

Usá el id de tu entidad (factura, pedido, cuota), no uno por intento. Si un create da timeout:

1. Hacé `GET /payment-request/{referenceId}`. Si da 200, el cobro se creó: usá esa respuesta.
2. Si da **404**, reintentá el `POST` con el mismo cuerpo y `referenceId`.
3. Si el `POST` da **409**, otro intento lo creó: volvé al paso 1.

Si el cobro del GET no coincide con lo que querías crear, reusaste por error un `referenceId` viejo.

## 4. Cancelá un cobro

Usá `POST /payment-request/{referenceId}/cancel`, sin cuerpo:

**cURL**

```bash
curl -X POST https://integration-api.test.chytapay.com.ar/payment-request/factura-1001/cancel \
  -H "Authorization: Bearer $ID_TOKEN"
```

**Respuesta**

```json
{ "referenceId": "factura-1001", "state": "canceled" }
```

Solo se cancelan cobros en `draft` o `pending` sin pagos: si no, **409** `PaymentRequestCannotBeCanceled`. No genera evento: la respuesta 200 es la confirmación. Si después entra una transferencia, llega `payment.unmatched` con `reason: "canceled"`, que es [opt-in](https://chytapay.com.ar/api/webhooks/#pago-sin-imputar).

## Campos

&#xA;Los campos de un cobro estándar. Los opcionales que no usás se omiten, no van en `null`. Los campos desconocidos se ignoran; los prohibidos por nombre dan 400.

| Campo                             | Obligatorio          | Reglas                                                                                                                                                                                                                              |
| --------------------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `referenceId`                     | Sí                   | 8 a 100 caracteres: letras, números, `-` y `_`. Ver [duplicados](https://chytapay.com.ar/api/crear-cobros/#duplicados).                                                                                                             |
| `description`                     | Sí                   | La ve el pagador. 3 a 500 caracteres.                                                                                                                                                                                               |
| `dueDates`                        | Sí                   | 1 o 2 fechas: ver [vencimientos](https://chytapay.com.ar/api/crear-cobros/#vencimientos).                                                                                                                                           |
| `customer`                        | Sí                   | El pagador (tabla de abajo).                                                                                                                                                                                                        |
| `amount`                          | No                   | Pesos, mayor a 0, mandá hasta 2 decimales, tope 200.000.000. Sin él, nace [borrador](https://chytapay.com.ar/api/crear-cobros/#borrador).                                                                                           |
| `surcharge`                       | Con monto y 2 fechas | `{ "type", "value" }` del segundo vencimiento. Prohibido sin `amount`.                                                                                                                                                              |
| `sendWhatsappNotification`        | No                   | [Avisos](https://chytapay.com.ar/api/crear-cobros/#avisos) por WhatsApp. Si lo omitís con monto, rige lo que elegiste en el Portal ([WhatsApp](https://chytapay.com.ar/api/funciones/#whatsapp-defaults)). Sin monto, solo `false`. |
| `sendEmailNotification`           | Con monto            | Avisos por email. Sin monto, solo `false`.                                                                                                                                                                                          |
| `sendWhatsappPaymentConfirmation` | No                   | Ver [confirmación de pago](https://chytapay.com.ar/api/crear-cobros/#confirmacion-de-pago).                                                                                                                                         |
| `reminderNotificationDate`        | No                   | `YYYY-MM-DD`. Reemplaza el recordatorio previo. Solo con monto.                                                                                                                                                                     |
| `deferredInitialNotificationDate` | No                   | `YYYY-MM-DD`. Difiere el aviso inicial. Solo con monto.                                                                                                                                                                             |
| `conciliationType`                | No                   | `cvu` (default) o `cuil`, el [recomendado](https://chytapay.com.ar/api/conciliacion/).                                                                                                                                              |
| `webhookUrl`                      | No                   | HTTPS, hasta 2048 caracteres. Reemplaza la [URL de webhook](https://chytapay.com.ar/api/webhooks/) para este cobro.                                                                                                                 |
| `metadata`                        | No                   | Strings: hasta 50 claves de 40 caracteres, valores de 500, 8 KB. Vuelve en el GET y los eventos.                                                                                                                                    |

| Campo de `customer` | Obligatorio                          | Reglas                                                                                         |
| ------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------- |
| `name`              | Sí                                   | 2 a 150 caracteres.                                                                            |
| `taxDocument`       | Con `conciliationType: "cuil"`       | CUIL de 11 dígitos o DNI de 7 u 8. En modo CVU se ignora.                                      |
| `email`             | Con `sendEmailNotification: true`    | Válido, hasta 320 caracteres.                                                                  |
| `phoneNumber`       | Con `sendWhatsappNotification: true` | `{ "countryCode": "+54", "number": "..." }`, 6 a 20 caracteres: dígitos, espacios y `+ - ( )`. |

Fuera de estas reglas, **400** con el detalle: consultá los [errores](https://chytapay.com.ar/api/operacion/).

## Vencimientos y recargo

`dueDates` lleva 1 o 2 fechas, posteriores a hoy y a 35 días o menos:

| Formato                 | Ejemplo             | Vence                                                                                         |
| ----------------------- | ------------------- | --------------------------------------------------------------------------------------------- |
| `YYYY-MM-DD`            | `"<FECHA_1>"`       | Al terminar ese día, hora Argentina.                                                          |
| `YYYY-MM-DDTHH:MM[:SS]` | `"<FECHA_1>T18:30"` | En ese minuto. Sin zona es `-03:00`; acepta `Z` o un offset. Al menos 3 minutos en el futuro. |

En borradores con hora, mandá siempre el offset explícito (por ejemplo, `<FECHA_1>T18:30-03:00`). Entre las 21 y las 24 de Argentina, la validación toma el día UTC: usá pasado mañana para una fecha sin hora.

Con hora, el cobro es de [corta duración](https://chytapay.com.ar/api/crear-cobros/#vida-corta). Con 2 fechas, el segundo elemento de `dueDates` lleva `surcharge`, obligatorio con monto (Chytapay no las reordena). Se debe `amount` hasta el primer vencimiento y `amount` más el recargo desde el día siguiente.

`type` es `percentage` (0 a 100, sobre el monto), `fixed` (pesos, hasta 200.000.000) o `none` (`value: 0`). Con `amount: 25000` y `{ "type": "percentage", "value": 10 }`, el segundo vencimiento es de 27.500, en `calculatedAmounts`.

## Cobros de corta duración

Para reservas, entradas o cualquier cobro que tiene que cerrarse en un horario, mandá el vencimiento con hora: `"<FECHA_1>T18:30"`. Cambia varias cosas respecto de una fecha sola:

|                   | Fecha sola                          | Con hora                                                                         |
| ----------------- | ----------------------------------- | -------------------------------------------------------------------------------- |
| Vence             | Al terminar ese día, hora Argentina | En ese minuto. Sin zona es `-03:00`                                              |
| Vencimientos      | 1 o 2, con recargo en el segundo    | **Uno solo**, sin recargo                                                        |
| Evento al vencer  | Ninguno                             | `payment_request.expired`                                                        |
| Avisos al pagador | Recordatorio un día antes           | Con menos de 24 horas no hay recordatorio previo: quedan el inicial y el del día |
| En bulk           | Sí                                  | No, da 400                                                                       |

Si el cobro se paga en el widget, [el cobro de checkout](https://chytapay.com.ar/api/widget/#cobro-checkout) vence entre 3 y 60 minutos.

## Borrador sin monto

Sin `amount`, el cobro nace en `draft`, con un vencimiento, sin recargo ni avisos (flags solo en `false`, fechas de aviso prohibidas). Su CVU no recibe pagos para ese borrador: una transferencia queda sin imputar (`no_pending`). Completalo con `PATCH /payment-request/{referenceId}`:

**cURL**

```bash
curl -X PATCH https://integration-api.test.chytapay.com.ar/payment-request/factura-1002 \
  -H "Authorization: Bearer $ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 18000 }'
```

**Respuesta**

```json
{
  "referenceId": "factura-1002",
  "previousAmount": null,
  "amount": 18000,
  "description": "Inscripción",
  "state": "pending",
  "dueDates": ["<FECHA_1>"]
}
```

- Solo en `draft` sin pagos; si no, **409**.
- Pasa a `pending`. Un borrador no envía avisos, ni después del PATCH.
- Si no lo completás, Chytapay lo descarta a partir de una hora sin modificaciones.

## Estados

Create, GET, cancel, PATCH y bulk devuelven `state`, y los eventos `payment_request.*`, `stateType`. No existe `PAID`: es `total_payment`.

| Estado               | Significa                                                                                       |
| -------------------- | ----------------------------------------------------------------------------------------------- |
| `draft`              | Borrador sin monto.                                                                             |
| `pending`            | Esperando el pago.                                                                              |
| `partial_payment`    | Pago parcial, queda saldo.                                                                      |
| `total_payment`      | Pagado.                                                                                         |
| `overdue`            | Venció sin pagos.                                                                               |
| `partial_overdue`    | Venció con un pago parcial.                                                                     |
| `canceled`           | Cancelado.                                                                                      |
| `refunded`           | Devuelto por completo. Ver [devoluciones](https://chytapay.com.ar/api/funciones/#devoluciones). |
| `partially_refunded` | Devuelto en parte.                                                                              |

Con 2 fechas, el cobro sigue abierto hasta el segundo vencimiento. Una fecha por día vence a las 00:00 hora Argentina, sin evento; una con hora vence en ese minuto con `payment_request.expired`. Consultá los eventos en [Webhooks](https://chytapay.com.ar/api/webhooks/).

## Avisos al pagador

&#xA;&#xA;
Un aviso es un WhatsApp o email de Chytapay al pagador (no un evento a tu backend). Los canales se eligen en los [campos](https://chytapay.com.ar/api/crear-cobros/#campos), solo con monto. Con un pago parcial los recordatorios salen con el saldo; pagado, vencido o cancelado, no salen.

### Cuándo sale cada aviso

Los recordatorios salen a las 10, hora Argentina.

| Aviso                                  | Cuándo                                                                      | Monto                                |
| -------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------ |
| Inicial                                | Al crear, o el día de `deferredInitialNotificationDate`                     | Primer vencimiento, sin recargo      |
| Recordatorio previo                    | Un día antes del primer vencimiento, o el día de `reminderNotificationDate` | Primer vencimiento, sin recargo      |
| Día del vencimiento                    | Ese día                                                                     | Primer vencimiento, sin recargo      |
| Primer vencimiento pasado (2 fechas)   | El día siguiente                                                            | Segundo vencimiento, **con recargo** |
| Día del segundo vencimiento (2 fechas) | Ese día                                                                     | Segundo vencimiento, **con recargo** |

Las dos fechas son posteriores a hoy y anteriores al primer vencimiento, y `reminderNotificationDate` además posterior a `deferredInitialNotificationDate`.

### Confirmación de pago

El aviso de pago recibido por WhatsApp lo controla `sendWhatsappPaymentConfirmation`, no `sendWhatsappNotification`:

| Valor   | Modo CVU                           | Modo CUIL             |
| ------- | ---------------------------------- | --------------------- |
| Omitido | Sale, en pagos totales y parciales | No sale               |
| `true`  | Sale, en pagos totales y parciales | Solo en el pago total |
| `false` | No sale                            | No sale               |

En modo CUIL el pagador puede pedirla con "Recibir confirmación de pago", y `false` no lo apaga.

## Creá cobros en bulk

`POST /payment-request/bulk` crea de 1 a 100 cobros, todos o ninguno. Cada ítem es un cobro individual, salvo que:

- Siempre concilia por CUIL: `customer.taxDocument` es obligatorio.
- El mismo documento dos veces en el lote da 422.
- Una fecha con hora da 400.
- No mandes `reminderNotificationDate` ni `deferredInitialNotificationDate`: no están soportadas en bulk.
- `conciliationType`, `type`, `expiresInMinutes` y `webhookUrl` están prohibidos: los eventos van a la URL de la integración.

En tu backend, mandá el lote:

**cURL**

```bash
curl -X POST https://integration-api.test.chytapay.com.ar/payment-request/bulk \
  -H "Authorization: Bearer $ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "paymentRequests": [
      {
        "referenceId": "cuota-2026-10-001",
        "amount": 12000,
        "description": "Cuota de octubre",
        "dueDates": ["<FECHA_1>"],
        "sendWhatsappNotification": false,
        "sendEmailNotification": false,
        "customer": { "name": "Nombre Apellido", "taxDocument": "20000000001" }
      },
      {
        "referenceId": "cuota-2026-10-002",
        "amount": 12000,
        "description": "Cuota de octubre",
        "dueDates": ["<FECHA_1>"],
        "sendWhatsappNotification": false,
        "sendEmailNotification": false,
        "customer": { "name": "Otro Pagador", "taxDocument": "30405060" }
      }
    ]
  }'
```

**Respuesta**

```json
{
  "batchId": "<uuid del lote>",
  "total": 2,
  "created": 2,
  "sharedCvu": "<CVU de 22 dígitos>",
  "accountInfo": {
    "accountHolderName": "<titular de la cuenta de comercio>",
    "accountHolderTaxId": "<CUIT del titular>",
    "bankName": "<banco>"
  },
  "paymentRequests": [
    { "referenceId": "cuota-2026-10-001", "state": "pending" },
    { "referenceId": "cuota-2026-10-002", "state": "pending" }
  ]
}
```

`paymentRequests` sigue el orden del request; el detalle se consulta con GET.

| Código  | Cuándo                                                                                                                                                     |
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **201** | Se crearon todos: guardá `batchId`.                                                                                                                        |
| **400** | Array vacío, más de 100 ítems o un campo fuera de contrato.                                                                                                |
| **422** | `errors: [{ index, referenceId, reason }]` con **todos** los ítems que fallaron: corregilos y reenviá el lote.                                             |
| **429** | El lote no entra entero en el tope de mensajes de WhatsApp: no se crea nada. Consultá [los límites](https://chytapay.com.ar/api/operacion/#respuesta-429). |

Con 400, 422 o 429 no se crea nada. Algunos `reason`, en inglés: `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: ...`.

`sendWhatsappPaymentConfirmation` vale para todo el lote y, si los ítems difieren, gana `false`. Los canales de aviso, al revés: si un ítem activa WhatsApp o email, queda activo para el lote.

## Cobro de checkout

Un cobro `type: "checkout"` se paga desde el widget: consultá [el cobro de checkout](https://chytapay.com.ar/api/widget/#cobro-checkout).

## Seguí por acá

- [Conciliación](https://chytapay.com.ar/api/conciliacion/): Por qué CUIL, cómo validar al pagador y cuándo usar CVU.
- [Webhooks](https://chytapay.com.ar/api/webhooks/): Eventos de pago y vencimiento, firma y reintentos.
- [Widget de checkout](https://chytapay.com.ar/api/widget/): Cobros de checkout pagados desde tu web.
- [Operación y errores](https://chytapay.com.ar/api/operacion/): Tope de mensajes, 429 y errores por endpoint.
