Saltar al contenido
ApiPay Hub · Docs

Modo test y sandbox#

El modo test no es un entorno aparte. Las claves pk_test_ y sk_test_ operan contra la misma https://api.apipay.io, con el mismo código y los mismos endpoints. Lo que cambia es la partición de los datos: todo lo que crea una clave de test nace con livemode: false y vive separado de lo real.

Modo testModo live
Clavespk_test_… / sk_test_…pk_live_… / sk_live_…
Base de la APIhttps://api.apipay.iohttps://api.apipay.io
livemode de los recursosfalsetrue
Pasarelas disponibleslas configuradas, más sandboxsolo las configuradas
Dineroninguno se muevese mueve de verdad
Endpoints de webhooklos de modo testlos de modo live

Cómo saber en qué modo estás#

Tres señales, en orden de fiabilidad:

  1. El prefijo de la clave: sk_test_ frente a sk_live_.
  2. El campo livemode de cualquier recurso que devuelva la API.
  3. El campo livemode del envelope de cada webhook.

La pasarela sandbox#

sandbox es una implementación de pasarela que no llama a ningún proveedor externo: resultados deterministas, inmediatos y gratuitos. Está en el catálogo como cualquier otra y se usa igual, con gateway_id: "sandbox".

Escenarios por los dos últimos dígitos de amount_minor#

El comportamiento se elige con los dos últimos dígitos del monto. No hay datos mágicos adicionales, ni cabeceras especiales, ni tarjetas de prueba: cualquier SDK reproduce cualquier escenario eligiendo el número.

amount_minor termina enQué simulaRecorrido del intent
00 (y cualquier otro no listado)Aprobación inmediataCREATEDPROCESSINGSUCCEEDED
05Fondos insuficientes: el confirm devuelve 402 card_declinedCREATEDPROCESSINGFAILED
13Timeout de pasarela: el confirm excede el timeout y un webhook simulado resuelve a los 60 sCREATEDPROCESSINGFAILED
42Requiere acción: redirect_url a una página del propio sandbox donde apruebas o rechazasCREATEDREQUIRES_ACTIONPROCESSINGSUCCEEDED o FAILED

En CLP, que tiene exponente 0, los dos últimos dígitos son pesos:

MontoSe leeEscenario
1499000$1.499.00000 → aprueba
1499005$1.499.00505402 card_declined
1499013$1.499.01313 → timeout, resuelve por webhook
1499042$1.499.04242REQUIRES_ACTION

En una divisa con exponente 2 los dos últimos dígitos son los centavos: 105000 en USD son $1050.00 y termina en 00, así que aprueba; 105005 son $1050.05 y se rechaza.

// Un escenario por monto. La misma llamada, distinto desenlace.
const escenarios = {
  aprueba: 1499000,
  rechaza: 1499005,
  timeout: 1499013,
  requiereAccion: 1499042,
} as const;
const created = await apipay.paymentIntents.create({
  amount_minor: escenarios.timeout,
  currency: 'CLP',
  gateway_id: 'sandbox',
  metadata: { escenario: 'gateway_timeout' },
});
const intent = await apipay.paymentIntents.confirm(created.id);
// intent.status === 'PROCESSING': el desenlace llega por webhook a los 60 s.
Quieres provocarCómo
402 card_declinedmonto acabado en 05 con gateway_id: "sandbox"
409 invalid_state_transitioncancel sobre un intent ya SUCCEEDED
409 idempotency_key_reuserepetir una Idempotency-Key con un cuerpo distinto
422 amount_exceeds_refundablereembolsar más que el saldo del intent
422 currency_not_supportedpedir una divisa que la pasarela no tiene habilitada para tu tenant
401 invalid_api_keyuna clave revocada, o una sk_live_ en el entorno de test
404 resource_not_foundun pi_ de la partición contraria
400 validation_errorgateway_id: "sandbox" con una clave sk_live_

El catálogo completo, con qué hacer ante cada uno, está en manejo de errores.


Disparar eventos de prueba desde el backoffice#

Desde admin.apipay.io, un TENANT_ADMIN puede enviar cualquier evento del catálogo (payment_intent.succeeded, refund.failed, …) contra un endpoint de webhook de modo test.

Lo importante es que reutiliza el pipeline real: el evento se inserta en la bandeja de salida, viaja por el mismo bus y lo entrega el mismo dispatcher, con firma ApiPay-Signature auténtica y livemode: false en el envelope. No es una simulación de la entrega: es la entrega.

Sirve para validar de extremo a extremo, sin crear un pago:

  • que tu verificación de firma funciona con el secreto que tienes desplegado,
  • que tu deduplicación por evt_ aguanta la misma entrega dos veces,
  • que tu handler responde 2xx en el tiempo que debe,
  • que un type que tu código no conoce se ignora sin romper nada.

Tarjetas y datos de prueba de las pasarelas reales#

Cuando pruebes contra el ambiente de integración de una pasarela de verdad, los datos de prueba los publica el proveedor. Este portal no los copia, a propósito: esas tablas cambian y una copia desactualizada es peor que un enlace.

PasarelaDocumentación oficial de datos de prueba
Transbank (Webpay Plus)Cómo empezar · Transbank Developers (se abre en una pestaña nueva) — ambiente de integración y tarjetas
MercadoPagoCuentas de prueba · MercadoPago Developers (se abre en una pestaña nueva) — usuarios de prueba y sandbox

La única tabla de escenarios que ApiPay mantiene como propia es la de sandbox, que está más arriba.

Cada guía por pasarela explica lo específico de su ambiente de integración: Webpay, MercadoPago.


Colección Postman#

El portal publica una colección Postman generada en CI desde contracts/openapi/payment-api.v1.yaml, con las variables baseUrl y apiKey ya definidas. Nunca se edita a mano: se regenera con cada cambio del contrato, así que no puede quedar desalineada con la referencia de API.


Antes de salir a live#

  • Las claves salen de configuración de entorno, nunca del código ni del bundle del frontend.
  • El proceso de producción usa sk_live_ y el de pruebas sk_test_, y no hay forma de confundirlos: variables con nombres distintos, no un flag.
  • gateway_id: "sandbox" no aparece en ninguna ruta de código que se ejecute en live.
  • Hay un endpoint de webhook por modo, cada uno con su propio whsec_.
  • El handler de webhooks pasó las cuatro pruebas de la guía de webhooks: cuerpo crudo, firma, deduplicación y 2xx rápido.
  • Probaste el escenario 13: tu integración no depende de que el confirm dé el resultado.
  • Probaste 05 y muestras un mensaje útil al pagador ante card_declined.
  • Persistes la Idempotency-Key de cada POST de cobro y de reembolso.
  • Tienes un job de conciliación para intents que llevan demasiado tiempo en PROCESSING o en REQUIRES_ACTION.
  • La pasarela real está configurada en el tenant, con credenciales de producción y sus divisas habilitadas.
  • Registras el X-Request-Id de las respuestas de error: es lo que pide soporte.

Siguientes pasos#

  • Webhooks: la guía que hay que leer antes de salir a live.
  • Manejo de errores: los 17 code y qué hacer con cada uno.
  • Payment intents: la matriz de transiciones que siguen los escenarios.
  • Quickstart: el recorrido completo en modo test, de cero a pago aprobado.