Desarrolladores · Documentación de la API

Alumnos y matrículas

Sincronizar alumnos y matrículas con EduPay sin duplicar: códigos externos, updated_since e Idempotency-Key.

Esta guía muestra cómo mantener alumnos y matrículas iguales en los dos sistemas, sin duplicar a nadie. Los campos completos de cada ruta están en la Referencia.

El catálogo: los números que usa la matrícula

Para matricular se necesita el número del curso (o trayecto), del grupo y del plan de pago. Vienen del catálogo (catalog:read):

Ruta Qué trae
GET /offerings Cursos (ofertas), con precio y estado
GET /trails Trayectos (varios cursos vendidos juntos)
GET /cohorts Grupos, con el estado (solo un grupo abierto recibe matrículas)
GET /financial-plans Planes de pago: formas aceptadas, cuotas, vencimiento y tasa de matrícula
GET /sales-pages Páginas de ventas publicadas, con el precio mostrado

Guarde esos números en la configuración de la integración. Cambian poco.

Código externo: su número dentro de EduPay

El alumno y la matrícula tienen el campo external_id, con el código del registro en su sistema (hasta 100 caracteres, único en la escuela). Grábelo al crear y úselo para encontrar el registro después:

curl "https://edupay.estudiosite.com/api/v1/students?external_id=ALU-0091" \
  -H "Authorization: Bearer $EDUPAY_KEY"

La escuela también puede completar el código en el panel, en la pantalla del alumno y de la matrícula.

Sincronizar con updated_since

Para traer solo lo que cambió desde la última vez, guarde la hora de inicio de cada sincronización y pásela en la siguiente:

curl "https://edupay.estudiosite.com/api/v1/students?updated_since=2026-10-29T12:00:00Z&limit=200" \
  -H "Authorization: Bearer $EDUPAY_KEY"

Recorra las páginas con cursor hasta que meta.has_more sea false. Funciona en alumnos, matrículas, cuotas y en el catálogo. Para saberlo en el momento, sin consultar de vez en cuando, use los Avisos automáticos.

Alumnos

Consultar (students:read): GET /students acepta email (sin distinguir mayúsculas), document_number (con o sin puntuación), external_id y status. GET /students/{id} trae el registro completo, con la dirección en address.

Registrar (students:write): POST /students. El alumno se crea con la cuenta de acceso al portal y recibe el e-mail de bienvenida con la contraseña temporal. Envíe "send_welcome_email": false para no enviarlo.

curl -X POST https://edupay.estudiosite.com/api/v1/students \
  -H "Authorization: Bearer $EDUPAY_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 4b0c8f2e-6a7d-4f1e-9c3b-1d2e3f4a5b6c" \
  -d '{
    "external_id": "ALU-0091",
    "full_name": "Maria Souza",
    "email": "maria@exemplo.com",
    "document_number": "52998224725",
    "phone": "11999990000",
    "address": { "zip_code": "01310-100", "line": "Av. Paulista", "number": "1000",
                 "neighborhood": "Bela Vista", "city": "São Paulo", "state": "SP", "country": "BR" }
  }'

Valen las mismas reglas del registro en el panel, y cambian de una escuela a otra:

  • el CPF (documento fiscal de persona física en Brasil), el teléfono y la dirección pueden ser obligatorios; el e-mail es obligatorio cuando el alumno entra al portal con el e-mail;
  • la escuela puede activar la verificación del CPF;
  • el CPF y el external_id no se repiten en la escuela. También se rechaza el CPF de un alumno eliminado: la escuela restaura el registro anterior en el panel;
  • el plan de la escuela puede tener un límite de alumnos (403 con code student_limit_reached).

Los errores de campo vuelven en errors, con los nombres de la API (address.line, y no el nombre de la columna).

Modificar: PATCH /students/{id} cambia solo lo que se envió. Si el alumno todavía no tenía cuenta en el portal y el dato de inicio de sesión pasa a existir, se crea la cuenta y sale el e-mail de bienvenida — igual que en la edición en el panel.

Abrir el portal con la sesión iniciada (portal:link): POST /students/{id}/portal-link devuelve una url que entra al portal del alumno sin contraseña. Vale 5 minutos y una sola vez: genérela en el momento del clic, nunca la deje guardada en una página. El alumno tiene que estar activo y tener e-mail y cuenta en el portal. En el primer acceso, el portal le pide definir una contraseña nueva.

Matrículas

Consultar (enrollments:read): GET /enrollments acepta student_id, external_id, offering_id, trail_id, cohort_id y status. Con include=student,installments,contract vienen los datos relacionados (cada uno con el permiso de su área). GET /enrollments/{id}/contract trae el estado del contrato y GET /enrollments/{id}/contract/pdf descarga el PDF.

Crear (enrollments:write): POST /enrollments, siempre con Idempotency-Key. El alumno viene por student_id o se registra en la misma solicitud en student (los mismos campos del registro). El producto viene por offering_id o trail_id.

curl -X POST "https://edupay.estudiosite.com/api/v1/enrollments?include=installments" \
  -H "Authorization: Bearer $EDUPAY_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: PED-2026-1187" \
  -d '{
    "external_id": "PED-2026-1187",
    "student_id": 532,
    "offering_id": 14,
    "cohort_id": 3,
    "financial_plan_id": 2,
    "payment_method": "pix"
  }'

La matrícula sigue exactamente el camino de la matrícula hecha en el panel:

  1. genera las cuotas según el plan de pago y, si hay un modelo, el contrato para firmar;
  2. si el grupo está vinculado a una cohorte de Moodle, inscribe al alumno en Moodle en el momento;
  3. emite los cobros: el enlace de tarjeta sale en el momento; el boleto y el PIX salen cuando el vencimiento entra en la ventana de emisión de la escuela (pocos días antes), como en el panel;
  4. avisa al alumno por e-mail.

Detalles:

  • Valores en centavos. Sin base_value, vale el precio del curso (o la suma de los cursos del trayecto). Sin enrollment_fee, vale la tasa del plan.
  • La forma de pago tiene que ser aceptada por el plan y por la cuenta de cobro de la escuela. Si no lo es, 422 en payment_method.
  • El curso, el trayecto y el plan tienen que estar activos, y el grupo, abierto.
  • Matrícula repetida: si el alumno ya tiene una matrícula vigente (esperando contrato, esperando pago o activa) en el mismo curso o trayecto, la respuesta es 409 con code enrollment_conflict y el número de la existente en existing_enrollment_id.
  • La matrícula queda a nombre de quien creó la clave en el panel.

Cancelar: POST /enrollments/{id}/cancel, con reason opcional (student_withdrawal, transfer, default o administrative). Las cuotas pendientes se cancelan junto con los cobros, el alumno recibe un aviso y sale de Moodle. La multa por rescisión sigue siendo solo por el panel. Un boleto todavía dentro de su validez no se puede cancelar en el banco y se puede pagar hasta que venza: meta.charges_still_payable dice cuántos.

Estados de la matrícula

status Significa
pending_contract Esperando que el alumno firme el contrato
pending_payment Esperando el primer pago
active Activa
cancelled Cancelada
completed Concluida (todas las cuotas resueltas)

Repetir sin duplicar

Se cae la red, se agota el tiempo, el sistema se reinicia a mitad del proceso. Para eso existe el encabezado Idempotency-Key: envíe un código único por solicitud (un UUID o el número del pedido en su sistema). Repetir la misma solicitud con la misma clave en hasta 24 horas devuelve la primera respuesta, con el encabezado Idempotent-Replayed: true, y no se graba nada de nuevo. Detalles en Errores y límites.