Integración CardNet en tu sitio
Captura tarjetas con el SDK PWCheckout de CardNet y completa sync, activación y cobros con la API de Gestiono
Esta guía es para sitios o apps que quieren capturar tarjetas con el SDK de CardNet (PWCheckout) en su propio frontend, y usar Gestiono para sincronizar el método, activarlo y cobrar (pago único o cobro automático de suscripciones).
Modelo recomendado
| Responsabilidad | Quién |
|---|---|
| Mostrar el iframe / captura de PAN / CVV | Tu sitio + SDK CardNet (PWCheckout) |
Crear sesión de captura (CaptureURL, UniqueID, clave pública) | Gestiono API |
Guardar / listar perfiles (PaymentProfileId) | Gestiono API (sync) |
Activar medio pendiente (ActivationCode) | Gestiono API |
| Cobrar factura / habilitar autocharge | Gestiono API |
| Clave privada CardNet y llamadas Purchase | Solo Gestiono (nunca en el navegador) |
Cliente → tu sitio → PWCheckout (CardNet)
↓ tokenCreated
Gestiono sync / activate / pay
↓
CardNet Purchase (servidor Gestiono)Requisitos
- Organización con CardNet configurado en Gestiono (clave pública + privada, ambiente Lab o Producción).
- Cliente (beneficiario) con email válido.
- Facturas / recurrencias en DOP para cobros CardNet (otras monedas son rechazadas).
- No exponer en el frontend: clave privada CardNet, ni el
Tokeninterno del perfil (CT__…). Usa siempre elPaymentProfileIdque devuelve Gestiono.
Dos flujos de API
A) Link de pago compartido (público)
Ideal si el cliente llega por un payment link de Gestiono (shareId). No requiere sesión de usuario Gestiono; el shareId identifica factura / suscripción y cliente.
Base: /v1/shared/{shareId}/…
B) Contacto autenticado (panel / app con API key)
Ideal si tu backend opera sobre un beneficiaryId con autenticación Gestiono (Autenticación).
Base: /v1/beneficiary/{beneficiaryId}/cardnet/…
El flujo de captura + activación es el mismo; cambian solo rutas y auth.
Paso 1 — Crear sesión de captura
Payment link
POST /v1/shared/{shareId}/cardnet/capture-session
Contacto
POST /v1/beneficiary/{beneficiaryId}/cardnet/capture-session
(requiere autenticación)
Respuesta
{
"captureUrl": "https://…/Capture/…",
"uniqueId": "…",
"publicAccountKey": "J_…",
"scriptUrl": "https://…/Scripts/PWCheckout.js?key=…"
}Gestiono asegura el Customer CardNet del beneficiario y devuelve lo necesario para abrir PWCheckout. No envíes tu PrivateAccountKey al navegador.
Paso 2 — Captura en tu sitio (PWCheckout)
- Carga
scriptUrlen la página. - Crea un formulario host con
idconocido (ej.cardnet-capture-form) y un input hiddenPWToken. CardNet exigeform_id. - Llama
PWCheckout.SetProperties(incluyeform_id,currency: 'DOP',autoSubmit: 'false', etc.). - Abre el iframe:
const session = await fetchCaptureSession() // desde Gestiono
await loadScript(session.scriptUrl)
// Formulario oculto requerido por CardNet
ensureHiddenForm('cardnet-capture-form')
PWCheckout.SetProperties({
button_label: 'Pagar #monto#',
description: 'Registro de tarjeta',
currency: 'DOP',
amount: '',
lang: 'ESP',
form_id: 'cardnet-capture-form',
checkout_card: 1,
autoSubmit: 'false',
empty: 'false',
})
PWCheckout.Bind('tokenCreated', async () => {
// No envíes el Token a tu servidor salvo que lo resuelva Gestiono;
// con Gestiono basta con sync — el perfil queda ligado al Customer.
await syncWithGestiono()
await refreshPaymentMethods()
})
const url =
session.captureUrl +
'?key=' + encodeURIComponent(session.publicAccountKey) +
'&session_id=' + encodeURIComponent(session.uniqueId)
PWCheckout.OpenIframeCustom(url, session.uniqueId)Referencia de implementación en Gestiono: captura con formulario host + SetProperties (mismo patrón que el checkout compartido).
Paso 3 — Sync (traer perfiles)
Tras tokenCreated, llama a Gestiono para que refresque los medios de pago CardNet del cliente.
Payment link
POST /v1/shared/{shareId}/cardnet/sync
Respuesta: { "success": true } — luego vuelve a cargar datos del link (GET /v1/shared/{shareId}/… / payment data) para ver savedPaymentMethods.
Contacto
POST /v1/beneficiary/{beneficiaryId}/cardnet/sync
Respuesta incluye data: lista de métodos (id, brand, last4, expiration, enabled, provider: 'cardnet').
Listar métodos (contacto)
GET /v1/beneficiary/{beneficiaryId}/payment-methods (o el endpoint de métodos de pago del beneficiario disponible en tu versión).
Cada método CardNet usa:
id=PaymentProfileId(string) — este es el valor que pasas a activate / pay / autocharge.enabled=falsesi el perfil aún requiere activación.
Paso 4 — Activación (autenticación del medio de pago)
Si CardNet deja el perfil con Enabled=false, el titular recibe un código de activación. Tu UI debe mostrarlo como pendiente y pedir el código.
Payment link
POST /v1/shared/{shareId}/cardnet/activate
{
"token": "118366",
"activationCode": "CODIGO_RECIBIDO_POR_EL_TITULAR"
}Contacto
POST /v1/beneficiary/{beneficiaryId}/cardnet/activate
Mismo body. Respuesta contact: lista actualizada en data.
Importante: el campo token del body de Gestiono es el PaymentProfileId (el id del método). Gestiono resuelve el Token real CardNet en servidor. No necesitas (ni debes) enviar el Token CT__… desde el navegador.
Hasta que enabled sea true, no podrás cobrar ni habilitar autocharge con ese medio.
Paso 5 — Cobrar o guardar para autocharge
Pago único (payment link)
POST /v1/shared/{shareId}/pay-with-saved
{
"paymentMethodId": "118366",
"provider": "cardnet"
}Respuesta exitosa típica: { "success": true, "redirectUrl": "https://…/shared/…/completed" }.
Restricciones:
- Solo DOP.
- El perfil debe estar activado (
enabled: true).
Cobro automático (suscripción / payment link de recurrencia)
POST /v1/shared/{shareId}/enable-auto-charge
{
"paymentMethodId": "118366",
"provider": "cardnet"
}Gestiono guarda el medio en la recurrencia (paymentMethodId + paymentMethodProvider: 'cardnet'). Los cobros posteriores los ejecuta Gestiono (cron / cargo manual) vía Purchase CardNet y liquidan la factura en Gestiono.
Checklist rápido
- Configurar CardNet en Gestiono (org).
capture-session→ cargarscriptUrl→SetProperties→OpenIframeCustom.- En
tokenCreated→sync. - Si
enabled === false→ UI de código →activateconPaymentProfileId. pay-with-savedoenable-auto-chargeconprovider: "cardnet".
Errores frecuentes
| Situación | Qué hacer |
|---|---|
| Captura declina en lab / iframe | Verificar SetProperties (form_id, currency: 'DOP', autoSubmit: 'false') y claves Lab. |
12 Invalid request al cobrar | Moneda no DOP, o request inválido; CardNet en Gestiono solo asienta DOP. |
| “requiere activación” | Completar activate antes de pay / autocharge. |
Exponer Token CT__… | No hacerlo; usa PaymentProfileId vía Gestiono. |
| Clave privada en el frontend | Nunca; solo Gestiono llama Purchase / Activate con PrivateAccountKey. |
Seguridad
- El PAN/CVV solo se digitan en el iframe CardNet.
- Tu sitio solo recibe el evento
tokenCreatedy habla con Gestiono. - Gestiono guarda claves privadas CardNet cifradas/secretas de organización y ejecuta Purchase en backend.
- Preferimos payment link o API autenticada de Gestiono; no reimplementes la API privada de CardNet en tu servidor salvo que CardNet/Gestiono lo acordara aparte.
Referencias
- Autenticación Gestiono
- Manual técnico CardNet (tokenización / PWCheckout) — entregado por CardNet a tu comercio
- Flujo de referencia en el producto: página de pago compartido Gestiono (
/shared/{shareId})