Ambientes
Simulador público, cuenta de prueba y producción, y cómo pasar de uno a otro.
Hay tres ambientes con el mismo contrato. Cambiar de ambiente es cambiar la base y la llave, sin tocar tu código.
| Simulador público | Cuenta de prueba | Producción | |
|---|---|---|---|
| Base | https://widget.fital.xyz/explorar/v1 | https://widget.fital.xyz/sandbox/v1 | https://widget.fital.xyz/v1 |
| Cuenta | No hace falta | Panel y KYB aprobado, automático | Panel, KYB aprobado e inscripción de FITAL |
| Llave | Pública de prueba | sk_test_fital_…, por empresa | sk_live_fital_…, con login reciente |
| Dinero | Nunca | Nunca; saldos ficticios | Real |
| Estado entre llamadas | No guarda | Sí, por empresa | Real |
| Idempotencia | No real | Real | Real |
| Webhooks | Script local | Simulados y firmados | Reales |
| IP permitidas | No aplica | Opcional | Obligatoria |
| Firma de webhook | Vector público | Obligatoria | Obligatoria |
X-Fital-Scenario | Sí | Sí | No aplica |
| Reinicio de datos | No hace falta | Sí, desde el panel | No existe |
| Rieles | Todos, sólo la forma | SPEI con CLABE 999; otro riel da 403 rail_not_enabled | Los habilitados a tu empresa |
| Límite de peticiones | 10 por segundo por IP | 5 por segundo por llave | Ver Límites |
| Tiempos | Inmediatos | Acortados | Reales de cada banco |
| Comisiones y tipos de cambio | Ejemplo | Ficticios | Reales |
| Revisiones y cumplimiento | No | Simulados por escenario, con tiempos ficticios | Reales; su duración no es predecible |
La cuenta de prueba es automática con KYB aprobado. Producción requiere además la inscripción de FITAL: sin ella, el panel responde 403 live_not_enabled al crear una llave sk_live_fital_…. Las respuestas de ambos simuladores llevan X-Fital-Environment: sandbox, y las de la cuenta de prueba, livemode: false en su JSON.
Qué no simula el simulador público
Estado entre llamadas, idempotencia real, saldos, tiempos, límites reales, comisiones, tipos de cambio, firmas ni KYB. Prueba la forma de tu integración, no su conducta. Para eso existe la cuenta de prueba.
Tres diferencias concretas. Una petición que no cumple el esquema, también si falta Idempotency-Key o es muy corta, responde 422 con invalid_request y sin señalar un campo, cuando la API real responde 400 con el detalle. Un escenario que no aplica a la operación responde 404 en formato application/problem+json. Y request_id del cuerpo de un error es fijo: el valor de cada petición viene en el encabezado X-Request-Id. Tu código de producción debe esperar siempre la forma de Errores.
Escenarios
Envía X-Fital-Scenario: <nombre> para elegir la respuesta.
| Escenario | Respuesta | Termina en | Enseña a manejar |
|---|---|---|---|
payment_completed | 202 processing | Pago completed | Termina en completed. |
payment_failed | 202 processing | Pago failed | El pago no se hizo y no queda dinero en tránsito. Si no ves failed, no repitas. |
payment_returned | 202 processing | Pago returned | Devolución después de completed. |
insufficient_funds | 422 insufficient_funds | No aplica | Saldo insuficiente. |
invalid_beneficiary | 422 invalid_beneficiary | No aplica | Cuenta destino inválida. |
idempotency_key_reused | 422 idempotency_key_reused | No aplica | Misma clave con otro cuerpo. |
pix_not_enabled | 403 not_enabled | No aplica | PIX sin activación vigente para tu empresa. |
invalid_request | 400 invalid_request | No aplica | Errores por campo en details.fields. |
invalid_api_key | 401 invalid_api_key | No aplica | Llave mala o revocada. |
forbidden_scope | 403 forbidden_scope | No aplica | Falta un scope. |
kyb_required | 403 kyb_required | No aplica | Empresa sin aprobación. |
ip_not_allowed | 403 ip_not_allowed | No aplica | IP fuera de la lista de la llave. |
not_found | 404 not_found | No aplica | Recurso ajeno o inexistente. |
rate_limited | 429 rate_limited | No aplica | Esperar lo que indique Retry-After. |
service_unavailable | 503 service_unavailable | No aplica | Reintento con espera. |
status_degraded | 200 | No aplica | Pausar sólo lo afectado. |
Respuesta es lo que devuelve la petición, y Termina en es el estado final del recurso. No aplica significa que la respuesta ya es el resultado. Un pago siempre nace en 202 processing: el final no llega en esa respuesta. En el simulador público lo ves al consultar GET /v1/payments/{id} con el mismo escenario. En la cuenta de prueba, el pago avanza solo hasta ahí y te llega por webhook.
Sin encabezado obtienes el camino feliz: 2xx, y en un pago, processing.
Estos escenarios existen sólo en la cuenta de prueba:
| Escenario | Respuesta | Termina en | Enseña a manejar |
|---|---|---|---|
payment_in_review | 202 processing | Pago completed | Revisión que termina en completed. |
payment_in_review_failed | 202 processing | Pago failed | Revisión que termina en failed. El tiempo real de una revisión no es predecible. |
payment_held | 422 in_review | No aplica | Sin pay_. Repite con la misma clave tras levantarse: crea un pago. |
payment_uncertain | 202 processing | Pago completed | Resultado sin confirmar: la misma clave repite la respuesta y otra clave recibe 409 payment_in_flight. |
account_restricted | 403 account_restricted | No aplica | Cuenta restringida, sin pay_. |
collection_paid | 201 pending | Cobro paid | Cobro que se paga, con su evento firmado. |
collection_expired | 201 pending | Cobro expired | Cobro que vence, con su evento firmado. |
receiving_account_not_enabled | 403 not_enabled | No aplica | Moneda sin activación para tu empresa. No abre nada. |
receiving_account_processing | 202 processing | undefined active | Alta sin confirmar: no devuelve datos. Repite sin el escenario con la misma clave y se abre. |
deposit_received | 201 active | Depósito received | Depósito con pagador ficticio, con su evento firmado. |
collection_paid y collection_expired se envían al crear el cobro, y deposit_received al crear la dirección de depósito. Lee el cobro con GET /sandbox/v1/collections/{id} y el depósito con GET /sandbox/v1/deposits; también llegan por webhook.
Errores comunes
401 wrong_environment: la llave no es de esa base. En el simulador público,sk_test_fital_…también recibe este error; su base eshttps://widget.fital.xyz/sandbox/v1.- Confiar en un
200del simulador público como prueba de que tu flujo funciona. Sólo prueba la forma.