> 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: "Primeros pasos" (https://chytapay.com.ar/api/getting-started/), actualizada el 2026-10-21.
> Índice completo para asistentes de IA: https://chytapay.com.ar/llms.txt

# Primeros pasos

Del alta en el portal al primer evento en tu backend, todo en Sandbox: credenciales, un comercio conectado, un cobro, el pago simulado y el webhook.

Al terminar vas a tener un cobro de Sandbox pagado con un pago simulado y el evento `payment_request.payment_received` en tu backend. No se mueve plata real.



1. [Registrate y configurá](https://chytapay.com.ar/api/getting-started/#credenciales): Portal y webhook
2. [Conseguí un comercio de prueba](https://chytapay.com.ar/api/getting-started/#conectar): Token de Sandbox
3. [Creá un cobro](https://chytapay.com.ar/api/getting-started/#crear-cobro): POST /payment-request
4. [Simulá el pago](https://chytapay.com.ar/api/getting-started/#simular-pago): solo en Sandbox
5. [Recibí el evento](https://chytapay.com.ar/api/getting-started/#recibir-evento): webhook en tu backend

## Antes de empezar

- Una **URL HTTPS pública** para webhooks. En desarrollo sirve un túnel.
- `curl`, Node 18 o posterior, o Python 3 con `requests`.



Definí la URL de la API de Sandbox en tu terminal. La de Producción está en [Operación y errores](https://chytapay.com.ar/api/operacion/#ambientes).

```bash
export API=https://integration-api.test.chytapay.com.ar
```

## 1. Registrate y configurá

Te registrás vos en el portal, sin esperar a nadie. Arrancás en Sandbox, el ambiente de pruebas.



1. Entrá a [chytapay.com.ar/portal/login](https://chytapay.com.ar/portal/login), elegí **Crear cuenta**, confirmá tu mail y completá los datos de tu empresa. Al terminar, el portal te muestra el `clientId` y el `clientSecret` de Sandbox.
2. Guardalos en tu gestor de secretos. El `clientSecret` se muestra una sola vez: si lo perdés, rotalo en [**Credenciales**](https://chytapay.com.ar/portal/credentials). En este recorrido no los usás: sirven para el OAuth con comercios reales.
3. Cargá tu URL de webhook HTTPS en [**Webhooks**](https://chytapay.com.ar/portal/webhooks), pestaña **Destino**. El token de validación es opcional, de 16 caracteres o más, y llega en el header `validation-token`.



## 2. Conseguí un comercio de prueba

La Integration API recibe como Bearer el `idToken` de una cuenta de comercio vinculada a tu integración. Dura 1 hora.

### Atajo en Sandbox: un comercio de prueba

En Sandbox no hace falta OAuth: el portal te da el token de un comercio de prueba ya vinculado. Entrá a [**Comercios**](https://chytapay.com.ar/portal/merchants), sección **Cuentas**, tocá **Generar tokens de prueba** y guardá el `idToken` como `COMMERCE_TOKEN`. Dura 1 hora: cuando venza, generá otro. Para comprobar a qué comercio pertenece el token, [llamá a `GET /me`](https://chytapay.com.ar/api/conectar-comercios/#confirmar-comercio).

### El flujo real: OAuth

En Producción, cada cuenta de comercio autoriza a tu integración con OAuth: authorize, vuelta a tu `redirect_uri` con `code` y `state`, y canje por tokens. La `redirect_uri` [no es la URL de webhook](https://chytapay.com.ar/api/conectar-comercios/#redirect-uri-vs-webhook). Consultá [cómo conectar comercios con OAuth](https://chytapay.com.ar/api/conectar-comercios/).

## 3. Creá un cobro

En tu backend, creá el cobro con el token del comercio y un vencimiento entre mañana y 35 días. Mandá `"conciliationType": "cuil"` y el CUIL o DNI del pagador en `customer.taxDocument`: el pago se imputa por el CUIL de quien transfiere ([por qué CUIL](https://chytapay.com.ar/api/conciliacion/#conciliar-cuil)).

**cURL**

```bash
DUE_DATE=$(date -d '+7 days' +%F 2>/dev/null || date -v+7d +%F)

curl -X POST "$API/payment-request" \
  -H "Authorization: Bearer $COMMERCE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "referenceId": "prueba-0001",
    "amount": 1500,
    "description": "Cobro de prueba",
    "dueDates": ["'"$DUE_DATE"'"],
    "conciliationType": "cuil",
    "sendWhatsappNotification": false,
    "sendEmailNotification": false,
    "customer": { "name": "Pagador de prueba", "taxDocument": "20123456786" }
  }'
```

**Node**

```js
const dueDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);

const res = await fetch(`${process.env.API}/payment-request`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.COMMERCE_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    referenceId: 'prueba-0001',
    amount: 1500,
    description: 'Cobro de prueba',
    dueDates: [dueDate],
    conciliationType: 'cuil',
    sendWhatsappNotification: false,
    sendEmailNotification: false,
    customer: { name: 'Pagador de prueba', taxDocument: '20123456786' },
  }),
});
const cobro = await res.json();
console.log(res.status, cobro.state, cobro.CVU);
```

**Python**

```python
import os
import requests
from datetime import date, timedelta

due_date = (date.today() + timedelta(days=7)).isoformat()

res = requests.post(
    f"{os.environ['API']}/payment-request",
    headers={"Authorization": f"Bearer {os.environ['COMMERCE_TOKEN']}"},
    json={
        "referenceId": "prueba-0001",
        "amount": 1500,
        "description": "Cobro de prueba",
        "dueDates": [due_date],
        "conciliationType": "cuil",
        "sendWhatsappNotification": False,
        "sendEmailNotification": False,
        "customer": {"name": "Pagador de prueba", "taxDocument": "20123456786"},
    },
)
cobro = res.json()
print(res.status_code, cobro["state"], cobro["CVU"])
```

**Respuesta**

```json
{
  "type": "standard",
  "paymentRequestId": "00000000-0000-0000-0000-000000000000",
  "referenceId": "prueba-0001",
  "amount": 1500,
  "description": "Cobro de prueba",
  "dueDates": ["2026-10-07"],
  "state": "pending",
  "sendWhatsappNotification": false,
  "sendEmailNotification": false,
  "customer": { "name": "Pagador de prueba", "taxDocument": "20123456786" },
  "CVU": "0000000000000000000000",
  "bankAccountInfo": { "accountHolderName": "...", "accountHolderTaxId": "...", "bankName": "..." }
}
```

Responde `201` con el cobro en `pending`. Guardá el `CVU` en la variable `CVU` para la [etapa 4](https://chytapay.com.ar/api/getting-started/#simular-pago).

- `referenceId` lleva de 8 a 100 caracteres (letras, números, `-` y `_`) y es único por integración y comercio, cancelados incluidos. Repetido da `409` `ReferenceIdAlreadyExists`: para probar de nuevo, cambialo.
- Con `amount`, `sendEmailNotification` es obligatorio. `sendWhatsappNotification` es opcional: si lo omitís, rige lo que elegiste en el Portal. En Sandbox, `false`.
- Montos en pesos, con hasta 2 decimales.

Los demás campos, el recargo, el borrador y los lotes están en [Crear cobros](https://chytapay.com.ar/api/crear-cobros/).

## 4. Simulá el pago

Simulá el pago total en el Portal, en [**Simulador**](https://chytapay.com.ar/portal/simulate): poné el CVU del cobro, el monto y los datos de quien paga: CVU origen, nombre origen y, como CUIL origen, el del cobro.

- Con el CUIL del cobro, el pago se imputa y llega `payment_request.payment_received`.
- Con otro CUIL no concilia y el evento es `payment.unmatched`.
- Si el evento no te llega, revisá que esté activado en [**Webhooks**](https://chytapay.com.ar/portal/webhooks) y que tengas una URL cargada en [**Webhooks**](https://chytapay.com.ar/portal/webhooks), pestaña **Destino**.

> **Atención:** **`payment.unmatched` viene apagado.** Activalo en [**Webhooks**](https://chytapay.com.ar/portal/webhooks?tab=eventos), pestaña **Eventos**: sin él no te enterás de los pagos sin imputar, como el de un tercero con otro CUIL.

## 5. Recibí el evento

Chytapay manda un `POST` a tu URL de webhook. Respondé `2xx` en menos de 5 segundos o reintenta.

| Header                  | Para qué                                                                         |
| ----------------------- | -------------------------------------------------------------------------------- |
| `X-Chytapay-Signature`  | Firma HMAC-SHA256, `t=<unix>,v1=<hex>`. Verificala antes de confiar en el evento |
| `X-Chytapay-Webhook-Id` | Igual en todos los reintentos: deduplicá por este id                             |
| `validation-token`      | El token que cargaste con la URL                                                 |

El body, recortado:

```json
{
  "event": "payment_request.payment_received",
  "stateType": "total_payment",
  "livemode": false,
  "referenceId": "prueba-0001",
  "requestedAmount": 1500,
  "paidAmount": 1500,
  "thisPaymentAmount": 1500,
  "remainingAmount": 0,
  "reconciledPayerCuil": 20123456786
}
```

Ruteá por `event` y decidí por `stateType`: `total_payment` o `partial_payment`. `livemode` es `false` en Sandbox.

El servidor de ejemplo, la verificación de la firma y los reintentos están en [Webhooks](https://chytapay.com.ar/api/webhooks/). Para probar solo tu endpoint, [**Webhooks**](https://chytapay.com.ar/portal/webhooks) tiene un botón que manda un `payment.unmatched` de prueba. No existe en producción.



## Pasar a producción

Es la misma integración: pedís Producción en [**Credenciales**](https://chytapay.com.ar/portal/credentials), y si el chequeo automático la aprueba generás las credenciales de producción con el selector de ambiente en Producción. Si no, el pedido pasa a revisión. Qué revisar antes de cobrar está en [Operación y errores](https://chytapay.com.ar/api/operacion/#produccion).

## Próximos pasos

- [Conectar comercios](https://chytapay.com.ar/api/conectar-comercios/): OAuth, tokens y desvinculación.
- [Crear cobros](https://chytapay.com.ar/api/crear-cobros/): Campos, estados y lotes.
- [Webhooks](https://chytapay.com.ar/api/webhooks/): Firma, reintentos y deduplicación.
