Cómo integrar Canonical
Aprenda cómo el controlador PSS Canonical le permite conectar un proveedor de servicios de pago a B2CORE implementando un contrato estándar de API de depósitos, incluida la configuración del lado de B2CORE, webhooks, sondeo y el ciclo de vida del estado de los depósitos.
El controlador Canonical le permite conectar un proveedor de servicios de pago (PSP) de su elección a B2CORE mediante PSS, incluso cuando B2CORE aún no ofrece un controlador dedicado para ese proveedor.
Por qué usar el controlador Canonical
La mayoría de los sistemas de pago en B2CORE se basan en un controlador dedicado creado específicamente para un proveedor. El controlador Canonical adopta un enfoque diferente: define un único contrato de API estándar —la API de depósitos Canonical— que cualquier proveedor puede implementar. Luego, B2CORE gestiona la autenticación, el flujo de inicio de depósitos, el sondeo, los webhooks y el ciclo de vida de los estados de forma uniforme, independientemente del proveedor que se encuentre detrás del contrato.
El controlador Canonical es útil cuando desea:
- Conectar un PSP preferido o interno que no tiene un controlador B2CORE dedicado, sin esperar desarrollo personalizado.
- Reducir el tiempo de comercialización haciendo que su proveedor implemente un contrato documentado y estable en lugar de una integración a medida.
- Mantener el control total del lado del proveedor, mientras B2CORE gestiona el flujo de trabajo de depósitos de su lado.
Actualmente, el controlador Canonical admite flujos de depósitos. Para ofrecer depósitos a través de su proveedor, este debe implementar la API de depósitos Canonical descrita en la especificación OpenAPI a continuación y seguir los requisitos de comportamiento de esta página.
Especificación OpenAPI
La API de depósitos Canonical se define en la siguiente especificación OpenAPI, que abarca autenticación, esquemas de solicitudes y respuestas, endpoints y códigos de estado. Descárguela para revisar el contrato completo que su proveedor debe implementar:
canonical-deposit-api.yaml
El resto de esta página describe los requisitos de comportamiento, la configuración del lado de B2CORE y las decisiones de diseño que la especificación no puede expresar. Lea ambos documentos conjuntamente para obtener una visión completa de la integración.
Credenciales del controlador B2CORE
Estos campos se configuran en el lado de B2CORE (Back Office) y se usan para autenticarse con la API del PSP. Consulte la especificación OpenAPI para obtener todos los detalles sobre la generación y verificación de tokens JWT.
| Campo | Descripción |
|---|---|
| URL base de API | URL base HTTPS de la API del PSP. |
| ID de aplicación | Identificador único del comerciante. Se utiliza como la declaración sub en el JWT. |
| Secreto de aplicación | Clave secreta para la firma HMAC-SHA256. Codificada en Base64 URL, 32 bytes (43 caracteres). Nunca se envía en solicitudes; solo se usa para firmar tokens. |
Campos de configuración del controlador B2CORE
Estos campos se configuran en el lado de B2CORE (Back Office) y controlan el comportamiento del controlador. No forman parte de la API orientada al PSP.
Parámetros globales (globalParam1, globalParam2, globalParam3)
Tres campos de cadena de texto a nivel de configuración que se envían con cada solicitud autenticada al PSP.
- Para los endpoints
POST, se incluyen en el cuerpo de la solicitud JSON. - Para los endpoints
GET, se incluyen como parámetros de consulta.
Estos representan valores específicos del PSP, como el ID de comerciante, el canal o el ID de proyecto. La semántica exacta depende de la implementación del PSP. El administrador de B2CORE los completa durante la configuración.
Campos obligatorios (solo lectura)
Tipo: Selección múltiple
Selecciona qué campos de información del usuario se muestran en el formulario de pago como solo lectura (no editables).
Los campos seleccionados deben estar ya configurados y guardados en el perfil B2CORE del usuario. Si falta algún campo seleccionado en el perfil, la generación del formulario de pago falla con un error de campos faltantes; el usuario no puede continuar hasta completar los datos en su perfil B2CORE.
Los campos seleccionados, junto con los campos de Campos obligatorios (editables), determinan qué datos de usuario se completan de forma significativa en el objeto startDepositUserInfo enviado al PSP en la solicitud POST /api/v1/deposits. Los campos que no estén seleccionados en ninguna de las listas se ocultan en el formulario y pueden enviarse como valores vacíos.
Campos obligatorios (editables)
Tipo: Selección múltiple
Selecciona qué campos de información del usuario se muestran en el formulario de pago como editables. El usuario puede completar o modificar estos campos directamente en el formulario de pago. A diferencia de Campos obligatorios (solo lectura), no es necesario que estos campos estén preconfigurados en el perfil B2CORE del usuario.
Regla de prioridad: Si un campo está seleccionado tanto en Campos obligatorios (solo lectura) como en Campos obligatorios (editables), se muestra como solo lectura. La configuración de solo lectura siempre tiene prioridad.
Comportamiento del correo electrónico: El correo electrónico siempre se muestra en el formulario de pago y siempre se envía en startDepositUserInfo, independientemente de si está seleccionado en alguna de las listas. La configuración solo controla cómo se muestra:
| Correo electrónico seleccionado en | Comportamiento |
|---|---|
| Ninguna lista | Se muestra como un campo editable |
| Campos obligatorios (editables) | Se muestra como un campo editable |
| Campos obligatorios (solo lectura) | Se muestra como un campo de solo lectura (valor del perfil B2CORE) |
| Ambas listas | Se muestra como un campo de solo lectura (solo lectura tiene prioridad) |
Plazo de sincronización predeterminado
Tipo: Selección
Predeterminado: 4h
Duración máxima después de la creación del depósito durante la cual B2CORE consulta el estado del depósito. Después de este plazo:
StatusSyncInProgress→ el depósito se mueve aunexpected.StatusSyncUnexpected→ el depósito se mueve aunexpected.
El estado unexpected requiere una investigación manual del administrador mediante LifecycleService.
Seguro para fallar al inicio
Tipo: Booleano (actualmente codificado de forma fija como yes, sin opción)
Determina si es seguro marcar un depósito como failed (terminal) cuando la solicitud de inicio encuentra un error inesperado.
yes— si el PSP devuelve un error durante el inicio del depósito y B2CORE está seguro de que el depósito no se creó en el lado del PSP (por ejemplo, B2CORE nunca recibió una URL de redirección), el depósito puede moverse de forma segura afailed. El cliente no ha perdido dinero.no— incluso en caso de error, el depósito se mueve ain_progresscon un ID externo no verificado y se consulta, porque el PSP podría haber creado el depósito a pesar del error.
Actualmente, siempre yes. El caso típico: sin una URL de redirección, el cliente no puede completar la página de pago del PSP, por lo que el depósito no puede realizarse correctamente.
Esperar el webhook antes de consultar
Tipo: Booleano (actualmente codificado de forma fija como yes, sin opción)
Controla si B2CORE espera una notificación webhook antes de comenzar a consultar GET /api/v1/deposits/{externalID}.
| Valor | Comportamiento |
|---|---|
yes | Después del inicio del depósito, B2CORE espera hasta 5 minutos un webhook antes de comenzar a consultar. Si no llega ningún webhook en 5 minutos, B2CORE procede con el sondeo estándar. |
no | B2CORE comienza a consultar inmediatamente según la programación estándar de retroceso progresivo. |
Justificación: Muchos PSP envían una notificación webhook rápidamente cuando cambia el estado del depósito. Esperar el webhook antes de consultar reduce la cantidad de llamadas API innecesarias, lo que ayuda a mantenerse dentro de los límites de tasa. El tiempo de espera de 5 minutos garantiza el progreso incluso si el webhook se retrasa o se pierde.
Flujo de prueba de configuración
Cuando un administrador hace clic en Probar configuración en B2CORE:
1. B2CORE generates a one-time JWT signed with appSecret
2. B2CORE → POST /api/v1/configuration/test (with Bearer JWT + globalParams)
3. If response status = "available" → test result: "available"
4. If response status = "failed" → test result: "failed" (with error from PSP)
5. If unexpected error (5xx, timeout, and similar) → test result: "unexpected"El método de prueba de configuración es el único método en el que se espera que cualquier problema de credenciales devuelva no 401 Unauthorized, sino 200 OK con un cuerpo de respuesta.
El code y la description se muestran al administrador de B2CORE, por lo que debe devolver datos limpios y no confidenciales.
Diseño del sistema de webhooks
Dos canales de webhook
B2CORE admite dos canales de webhook por depósito:
| Canal | Registro | Descripción |
|---|---|---|
| Automático | Mediante notificationURL en la solicitud POST /api/v1/deposits | Siempre activo. B2CORE genera la URL y la pasa al PSP. |
| Configurable por administrador | Configurado por el administrador en el Back Office de B2CORE | Opcional. El administrador puede configurar una URL de webhook independiente a la que el PSP envía notificaciones (por ejemplo, registrada en el panel de administración del PSP). |
Ambos canales alimentan el mismo controlador de webhook de B2CORE → almacenamiento driver_transit → canalización de optimización del sondeador.
Webhook como optimización del sondeo
El webhook no es la fuente de verdad. Es una optimización que reduce las solicitudes de sondeo innecesarias.
PSP → B2CORE webhook handler → driver_transit (key-value store) → pollerCómo funciona:
- Cuando llega un webhook, B2CORE almacena una marca en
driver_transitindexada porexternalID. - El sondeador verifica
driver_transitantes de realizar una llamada API:- Si existe una marca de webhook para el
externalID, B2CORE llama inmediatamente aGET /api/v1/deposits/{externalID}. - Si no existe ninguna marca y han pasado menos de 5 minutos, B2CORE espera (consulte Esperar el webhook antes de consultar).
- Si no existe ninguna marca y han pasado más de 5 minutos, B2CORE continúa con el sondeo estándar.
- Si existe una marca de webhook para el
- Cuando el depósito alcanza un estado terminal (correcto o fallido), se elimina la entrada de
driver_transit.
Carga útil del webhook
La carga útil del webhook es mínima (consulte la devolución de llamada del webhook en POST /api/v1/deposits en la especificación OpenAPI):
{
"externalID": "550e8400-e29b-41d4-a716-446655440000",
"status": "success"
}La carga útil contiene los siguientes campos:
externalID— coincide con el UUID de la solicitudPOST /api/v1/deposits.status— uno de"success","failed"o"unprocessable".
El webhook debe enviarse solo cuando el depósito cambia a un estado terminal.
Flujo de inicio de depósito
Solicitud de inicio
B2CORE inicia un depósito llamando a POST /api/v1/deposits.
La solicitud incluye un campo returnURL: una URL de página de frontend de B2CORE a la que redirigir al usuario después de la interacción con la página del PSP. Esto no es un webhook; es solo una redirección del navegador.
Para todos los demás detalles, consulte la especificación OpenAPI.
Asignación del resultado de inicio
La respuesta del PSP se asigna a una acción de B2CORE de la siguiente manera:
| Respuesta del PSP | Acción de B2CORE |
|---|---|
| El PSP devuelve una URL de redirección | Mover a in_progress |
| 2xx con una infracción de la especificación (por ejemplo, sin URL de redirección) | Mover a failed |
| Error HTTP 4xx / 5xx / tiempo de espera / error de red | Mover a failed |
Todos los escenarios de error resultan en failed (no unexpected) porque Seguro para fallar al inicio es yes (consulte Seguro para fallar al inicio): sin una URL de redirección válida, el usuario final no puede interactuar con la página de pago del PSP, por lo que no se puede perder dinero.
Flujo de redirección
En un inicio correcto, B2CORE recibe una URL de redirección y envía al usuario final a la página de pago del PSP:
sequenceDiagram
participant B as B2CORE
participant P as PSP
participant U as End user
B->>P: POST /api/v1/deposits
P-->>B: 200 OK<br/>action.type: "redirect"<br/>action.redirect.url: "..."
B->>U: Redirect end user to PSP payment page
U->>P: Open PSP payment page
U->>P: Complete payment
P-->>U: Redirect to returnURL
U->>B: Land on B2CORE "in progress" page- La
returnURLlleva al usuario de vuelta a una página de frontend de B2CORE que indica que el depósito está siendo procesado. - Después del inicio, B2CORE comienza el flujo de sondeo y webhook (consulte Sondeo y sincronización de estado).
- Actualmente,
"redirect"es el único tipo de acción admitido.
Sondeo y sincronización de estado
Programación de retroceso del sondeo
B2CORE utiliza retroceso progresivo para consultar GET /api/v1/deposits/{externalID}:
| Tiempo desde el inicio del depósito | Intervalo de sondeo |
|---|---|
| 0–15 minutos | Cada 1 minuto |
| 15–60 minutos | Cada 3 minutos |
| 1–3 horas | Cada 5 minutos |
| 3–5 horas | Cada 10 minutos |
| Más de 5 horas | Cada 15 minutos |
Gestión del plazo
Plazo predeterminado: 4 horas después de la creación del depósito (configurable; consulte Plazo de sincronización predeterminado).
Cuando se supera el plazo, los estados intermedios se resuelven de la siguiente manera:
| Último resultado del sondeo | Acción de B2CORE |
|---|---|
inProgress | Mover a unexpected |
| Error de red, 5xx, error de análisis y similares | Mover a unexpected |
El estado unexpected detiene el sondeo automático y requiere una acción manual del administrador mediante LifecycleService de B2CORE.
Lógica de espera del webhook
Cuando Esperar el webhook antes de consultar es yes (valor predeterminado actual; consulte Esperar el webhook antes de consultar):
flowchart TD
A["t=0min: deposit created, redirect URL returned<br/>Poller scheduled but WAITS for webhook"] --> B{Webhook received<br/>before t=5min?}
B -- yes --> C["Immediately poll<br/>GET /api/v1/deposits/{externalID}"]
B -- "no (t=5min elapsed)" --> D["Begin standard polling<br/>(1-minute intervals initially)"]
C --> E[Continue with standard<br/>polling backoff]
D --> E
E --> F[Continue until terminal status<br/>or deadline]Asignación de resultados del sondeo
Cada resultado de sondeo de GET /api/v1/deposits/{externalID} se asigna a una acción interna de B2CORE:
| Estado de respuesta del PSP | Acción de B2CORE |
|---|---|
"inProgress" + plazo no superado | Continuar el sondeo (reintentar) |
"inProgress" + plazo superado | Mover a unexpected |
"success" | Mover a success, detener el sondeo. Guardar finalAmount y finalCurrencyCode |
"failed" | Mover a failed, detener el sondeo. Guardar reason |
"unprocessable" | Mover a unexpected, detener el sondeo. Guardar reason. Requiere investigación del administrador |
| Error HTTP 5xx / tiempo de espera / error de análisis | Tratar como un intento de sondeo unexpected. Continuar el sondeo si no se ha superado el plazo |
HTTP 404 con X-Safe-To-Fail-After-Seconds | Continuar el sondeo. Después del tiempo indicado más un margen de seguridad (5 minutos), si sigue siendo 404, mover a failed con el motivo "deposit redirect URL is expired" |
| HTTP 404 sin el encabezado | Continuar el sondeo. Esperar a que el depósito aparezca en el lado del PSP o a que se supere el plazo de sincronización |
Ciclo de vida del estado de depósito
Esta sección describe los estados de depósito de B2CORE. Para la asignación de estados de respuesta del PSP a estados de B2CORE, consulte Asignación del resultado de inicio y Asignación de resultados del sondeo.
Diagrama completo de estados
flowchart TD
created[created]
post["POST /api/v1/deposits"]
failed1[failed]
inProgress1[in_progress]
unexpected1[unexpected]
poll["GET /api/v1/deposits/{externalID}<br/>(polling)"]
retryIP["(in_progress)<br/>(retry)"]
retryUX["(unexpected)<br/>(retry)"]
success[success]
failed2[failed]
unprocessable["(unprocessable)<br/>(stop polling)"]
inProgress2[in_progress]
created --> post
post --> failed1
post --> inProgress1
inProgress1 --> poll
poll --> retryIP
poll --> retryUX
poll --> success
poll --> failed2
poll --> unprocessable
retryIP --> inProgress2
retryUX --> inProgress2
unprocessable --> unexpected1
unexpected1 -->|Manual recovery| inProgress2Recuperación desde el estado unexpected
Un administrador puede realizar estas transiciones manuales mediante LifecycleService:
| Transición | Cuándo usarla |
|---|---|
unexpected → in_progress | Reintentar el sondeo (por ejemplo, después de resolver una interrupción del PSP) |
unexpected → success | Solo si el último intento de sondeo fue unprocessable y el administrador confirma el éxito |
unexpected → failed | El administrador confirma que el depósito falló |
Definiciones de estados de depósito
La siguiente tabla define cada estado de depósito de B2CORE:
| Estado | Significado empresarial |
|---|---|
in_progress | El depósito está siendo procesado. Cubre todos los estados intermedios: transferencia bancaria pendiente, verificación 3DS en curso, espera de revisión manual en el lado del PSP, el cliente interactuando con la página de pago del PSP y similares. Este es un estado no terminal; B2CORE continúa consultando. |
success | El bróker ha recibido el dinero del cliente. El PSP ha confirmado que los fondos se acreditaron. Los campos finalAmount y finalCurrencyCode reflejan el importe y la moneda reales recibidos, que pueden diferir de la solicitud inicial debido a comisiones o conversión. |
failed | El depósito no se realizó. El cliente no perdió dinero y el bróker no recibió fondos. Ejemplos: tarjeta rechazada, transferencia bancaria rechazada, usuario canceló en la página del PSP o enlace de redirección caducado. |
unexpected | El depósito no pudo resolverse automáticamente y requiere una acción manual del administrador mediante B2CORE (consulte Recuperación desde el estado unexpected); el sondeo automático se ha detenido. Se ingresa en este estado cuando vence el plazo mientras está in_progress o cuando el PSP informa unprocessable. |
Momento de creación del depósito
Los PSP siguen uno de dos patrones para la creación de depósitos:
| Patrón | Comportamiento | Impacto en el sondeo |
|---|---|---|
| Creación inmediata | El PSP crea el registro de depósito en POST /api/v1/deposits. | GET /api/v1/deposits/{externalID} devuelve un resultado inmediatamente después del inicio. |
| Creación diferida | El PSP crea el registro de depósito solo después de que el usuario final completa la página de pago del PSP. | GET /api/v1/deposits/{externalID} devuelve 404 Not Found hasta que el usuario completa la página. |
Para la creación diferida, el PSP debe devolver el encabezado X-Safe-To-Fail-After-Seconds con la respuesta 404. Este encabezado indica a B2CORE cuánto tiempo es válido el enlace de redirección. Después de redirect_time + header_value + safety_margin, si el depósito sigue siendo 404, B2CORE lo marca como failed con el motivo "deposit redirect URL is expired".
Si el encabezado está ausente, B2CORE continúa consultando hasta que aparezca el depósito o se supere el plazo de sincronización (4 horas de forma predeterminada), momento en el que el depósito se mueve a unexpected.
Requisitos de comportamiento
Trazabilidad distribuida
Todas las solicitudes HTTP de B2CORE al PSP incluyen encabezados de trazabilidad estándar conforme a la especificación W3C Trace Context:
traceparent— contiene el ID de traza, el ID del span principal y las marcas de traza.tracestate— datos de traza específicos del proveedor.
Las implementaciones del PSP deben propagar estos encabezados a sus servicios posteriores para permitir la observabilidad de extremo a extremo.
Bloqueo de moneda en la página de pago del PSP
Cuando la respuesta de inicio de depósito incluye una redirección a una página de pago del PSP:
- La página del PSP no debe permitir que el usuario final cambie el
currencyCodea ninguna moneda análoga, equivalente o alternativa. - La moneda mostrada en la página del PSP debe coincidir exactamente con la enviada en la solicitud de inicio de depósito.
- Si la página del PSP permite seleccionar una moneda, esta debe estar preseleccionada y bloqueada.
Recomendación de lista blanca de IP
Aunque no es obligatorio según la especificación de la API, se recomienda encarecidamente que las implementaciones del PSP configuren una lista blanca de IP de su lado. Esto proporciona una capa adicional de seguridad más allá de la autenticación JWT, limitando el acceso a la API a direcciones IP conocidas de B2CORE.
Para que el controlador Canonical esté disponible en su entorno, póngase en contacto con su gestor de cuenta. Indique exactamente cómo y para qué fines planea utilizar el controlador Canonical para que podamos organizar el acceso según corresponda.
Última actualización