Llaves y entornos #

¿Dónde pongo el id de mi caja o de mi entidad? #

En ninguna parte. La llave cmp_... identifica al tenant; el gateway lo resuelve solo. Los afiliados, pacientes o titulares se identifican con su document.

Llamo a la URL de sandbox y se ejecutó algo real. ¿Por qué? #

Porque lo que decide si la respuesta es simulada o real es la llave, no la URL. Una llave de producción llega al motor real en cualquier URL. Separa las llaves por entorno (Entornos y llaves).

Recibo 403 con una llave que funcionaba. #

Puede estar revocada o vencida, puede faltarle el scope de esa operación, tu entidad puede no tener el módulo contratado o tu IP puede no estar en la lista permitida. Llama a system.health() para ver los scopes y lee detail (Autenticación).

¿Cuál es la URL de producción? #

La que declara el contrato es https://api.compense.co; la definitiva se confirma en el onboarding. Pásala como URL base si difiere.

Idempotencia y errores #

¿Tengo que enviar Idempotency-Key? #

Sí en toda escritura. Es obligatoria en P2P, Bre-B, pago de facturas y recargas (sin ella, 400). Los SDK la generan si no la das, pero conviene una estable por operación de negocio (Idempotencia).

Recibí IdempotencyConflictError pero no reutilicé ninguna llave. #

Los SDK convierten todo 409 en esa excepción, y el motor usa 409 para rechazos de negocio (BILL_ALREADY_PAID, SLOT_NOT_AVAILABLE, REFERENCE_REUSED…). Si problem.type no termina en /idempotency-conflict, es un rechazo: lee detail (Errores).

Mi petición dio timeout. ¿Se hizo o no? #

No lo sabes, y por eso existe la idempotencia: reenvíala con la misma Idempotency-Key. Si ya se hizo, recibirás la respuesta guardada con idempotent_replay: true.

¿Por qué el SDK no reintenta mis escrituras? #

Porque no puede saber si el gateway que tiene enfrente deduplica, y reintentar contra uno que no lo haga duplicaría la operación. Actívalo con retry_writes cuando lo sepas (Reintentos).

¿Qué le envío a soporte cuando algo falla? #

El trace_id del error (igual a la cabecera X-Request-ID), la hora, la operación y tu Idempotency-Key. Nunca la llave ni datos personales completos.

Montos #

¿Envío los montos como número? #

No: como texto decimal ("467009.88"). Los SDK aceptan enteros, decimales o texto y envían el texto exacto (Montos).

Webhooks #

La firma nunca coincide. #

Casi siempre es porque se verifica un cuerpo re-serializado. Calcula el HMAC sobre los bytes crudos recibidos (en Express, express.raw(); en Laravel, $request->getContent(); en ASP.NET Core, copia Request.Body) y usa el secreto como texto UTF-8 (Verificar la firma).

Me llega el mismo evento dos veces. #

La entrega es al menos una vez: deduplica por X-Webhook-Id (event_id). Responde 2xx en menos de 10 segundos y procesa en segundo plano para evitar reintentos innecesarios.

Perdí el secreto de mi endpoint. #

No se puede recuperar: rótalo. El anterior deja de valer al instante, así que despliega primero un receptor que acepte ambos (Rotar el secreto).

¿Recibo webhooks reales en el sandbox? #

No: en el sandbox las pruebas y reentregas son simuladas ("simulated": true). Para entregas firmadas reales usa el entorno dev con una llave de producción (Probar webhooks).

Sandbox #

¿Qué documentos uso para probar? #

1000000001 (elegible), 1000000002 (inelegible), 1000000003 (revisión manual), 1000000004 (con deudas) y 9999999999 (no existe), entre otros por módulo (Datos de prueba).

¿Los afiliados se simulan? #

No. La consulta, el cruce y la carga de afiliados usan el registro real de tu tenant con cualquier llave.

SDK #

¿Qué SDK uso? #

El de tu lenguaje: los cinco cubren las 115 operaciones con las mismas reglas (SDK). Si tu lenguaje no tiene SDK, usa HTTP directo con la referencia del API.

¿Los SDK firman las peticiones de alto valor (X-Compense-Signature)? #

No en la versión 1.1.0. Si tu llave tiene la firma activada, añade la cabecera con un cliente HTTP propio (Autenticación).