Saltar al contenido
ESENIr al Portal

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.

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.

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

1Registrate 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, 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. En este recorrido no los usás: sirven para el OAuth con comercios reales.
  3. Cargá tu URL de webhook HTTPS en Webhooks, pestaña Destino. El token de validación es opcional, de 16 caracteres o más, y llega en el header validation-token.

2Conseguí 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, 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.

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. Consultá cómo conectar comercios con OAuth.

3Creá 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).

cURL

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

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

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

{
  "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.

  • 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.

4Simulá el pago

Simulá el pago total en el Portal, en Simulador: 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 y que tengas una URL cargada en Webhooks, pestaña Destino.

Atención: payment.unmatched viene apagado. Activalo en Webhooks, pestaña Eventos: sin él no te enterás de los pagos sin imputar, como el de un tercero con otro CUIL.

5Recibí 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. Para probar solo tu endpoint, 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, 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.

Próximos pasos