Las tarjetas virtuales proporcionan una forma segura de realizar pagos en línea sin exponer información financiera sensible. Las características incluyen:
Creación Instantánea: Las tarjetas se crean inmediatamente
Cumplimiento PCI: Manejo seguro de datos de tarjetas
Múltiples Tarjetas: Los usuarios pueden tener múltiples tarjetas
Saldos en Tiempo Real: Consulta saldos en múltiples activos
Historial de Transacciones: Seguimiento completo de transacciones
El campo detailsUrl proporciona una URL segura y compatible con PCI donde los usuarios pueden ver su número de tarjeta completo, CVV y fecha de expiración:
view-card-details.ts
const card = await bloque.accounts.card.create({ holderUrn: userUrn, name: 'Mi Tarjeta',});// Redirect user to view card detailsconsole.log('Ver detalles de tarjeta:', card.detailsUrl);
Seguridad
Nunca almacenes o registres números de tarjeta completos, CVVs u otros datos sensibles de tarjetas. Usa siempre el detailsUrl proporcionado para mostrar los detalles de la tarjeta a los usuarios.
Los controles de gasto determinan cómo se procesan las transacciones con tarjeta, incluyendo qué cuentas se debitan, cómo funciona la conversión multicurrency y cómo se enrutan los fondos. El modo de control de gasto se configura a través del metadata de la tarjeta al crearla o actualizarla.
El modo por defecto debita una única cuenta de tarjeta. Soporta conversión automática de moneda cuando la moneda de la transacción difiere del activo de la tarjeta.
create-card-default.ts
const card = await userSession.accounts.card.create({ urn: userUrn, name: 'Tarjeta Estándar', metadata: { spending_control: 'default', // Opcional, es el valor por defecto default_asset: 'DUSD/6', // Activo principal de la tarjeta fallback_asset: 'KSM/12', // Usado cuando el activo principal no está disponible currency_asset_map: { // Mapea monedas de transacción a activos preferidos USD: ['DUSD/6'], COP: ['COPM/2'], EUR: ['EURc/6'], }, },});
Campo
Tipo
Requerido
Descripción
spending_control
string
No
Establecer como "default" (o no incluir).
default_asset
string
No
Activo principal (ej. "DUSD/6"). Por defecto "DUSD/6".
fallback_asset
string
No
Activo de respaldo cuando el principal no está disponible.
currency_asset_map
object
No
Mapea códigos de moneda ISO 4217 a un array de identificadores de activos.
whatsapp_notification
boolean
No
Habilitar notificaciones de compra por WhatsApp. Por defecto true.
El gasto inteligente permite enrutamiento multi-bolsillo basado en Códigos de Categoría de Comercio (MCC). Las transacciones se enrutan a subcuentas (bolsillos) según la categoría del comercio, y el excedente se maneja por bolsillos de menor prioridad.
Puedes proporcionar las whitelists de MCC como arrays en línea o como URLs que apuntan a un array JSON. Usar URLs facilita actualizar las whitelists sin modificar el metadata de la tarjeta.
Las comisiones se pueden configurar en dos niveles usando el array spending_fees. Cada comisión puede ser incondicional o estar controlada por una regla que evalúa el contexto de la transacción al momento de la autorización.
Las comisiones se fusionan a través de tres capas por fee_name. Cada capa puede sobreescribir comisiones específicas de la capa inferior y agregar nuevas. Las comisiones que no se redefinen en una capa superior siempre se preservan.
Capa
Fuente
Descripción
Base
Por defecto
Comisiones predeterminadas (1.44% interchange + 2% FX). Siempre presentes a menos que se sobreescriban explícitamente por nombre.
+
Metadata de origen
spending_fees en el metadata del origen. Puede sobreescribir valores por defecto y agregar nuevas comisiones para todas las tarjetas.
+
Metadata de tarjeta
spending_fees en el metadata de la cuenta de tarjeta. Puede sobreescribir comisiones del origen/defecto y agregar nuevas para esta tarjeta específica.
Por ejemplo, si los valores por defecto definen interchange y fx, el origen agrega premium, y la tarjeta sobreescribe fx:
Comisión
Por defecto
+ Origen
+ Tarjeta (final)
interchange
1.44%
1.44%
1.44%
fx
2.00%
2.00%
1.50% (sobreescrito por tarjeta)
premium
—
0.50%
0.50%
Las Comisiones Base No Se Pueden Eliminar
Las comisiones de capas inferiores siempre se preservan. Una tarjeta u origen puede cambiar el value, type, account_urn o rule de una comisión existente redefiniéndola con el mismo fee_name, pero no puede eliminar una comisión por completo.
Las comisiones a nivel de tarjeta sobreescriben las del origen para una tarjeta específica. Se configuran en metadata.spending_fees al crear o actualizar la tarjeta:
Las comisiones a nivel de tarjeta se fusionan por fee_name. Solo necesitas incluir las comisiones que deseas sobreescribir o agregar — todas las demás comisiones del origen y los valores por defecto se preservan automáticamente.
type SpendingFeeCategory = 'fx' | 'interchange' | 'custom';interface SpendingFee { fee_name: string; // Identificador único (ej. "interchange", "fx") account_urn: string; // Cuenta destino para la comisión type: 'percentage' | 'flat'; value: number; // Tasa (0.02 = 2%) para porcentaje, o monto para fijo category?: SpendingFeeCategory; // Propósito de la comisión (por defecto "custom") rule?: string; // Opcional: nombre de regla condicional rule_params?: Record<string, unknown>; // Opcional: parámetros para la regla}
Tipo de Comisión
Significado de value
Ejemplo
percentage
Fracción del monto de la transacción
0.0144 = 1.44%
flat
Monto fijo en el activo de la transacción
100000 (escalado)
Categoría
Propósito
fx
Controla el spread del tipo de cambio en conversiones de moneda. Múltiples comisiones fx se suman.
interchange
Comisión de intercambio estándar.
custom
Valor por defecto para cualquier otra comisión.
Categoría FX y Spread de Conversión
Las comisiones con category: "fx" controlan directamente el spread del tipo de cambio aplicado durante las conversiones de moneda. Por ejemplo, una comisión fx con value: 0.02 resulta en un spread del 2% (tasa multiplicada por 0.98). Si múltiples comisiones tienen category: "fx", sus valores se suman para determinar el spread total. Si no se configuran comisiones con categoría fx, se usa el spread por defecto del 2%.
Las comisiones sin campo rule siempre se aplican. Las comisiones con una regla se evalúan contra la solicitud completa de la transacción al momento de la autorización.
Regla
Descripción
Parámetros
fx_conversion
Se aplica cuando la transacción requirió conversión de moneda (el activo de gasto difiere de la moneda de la transacción).
Ninguno
amount_range_usd
Se aplica cuando el monto de liquidación en USD cae dentro de un rango.
min?: number, max?: number
wallet
Se aplica cuando la transacción se realizó a través de una billetera de tokenización específica (coincidencia parcial, sin distinción de mayúsculas).
wallet_name: string
Cálculo de Comisiones
Las comisiones se calculan usando aritmética BigInt para evitar problemas de precisión de punto flotante. Durante reembolsos parciales (ajustes), las comisiones se recalculan proporcionalmente basándose en el monto del reembolso relativo a la autorización original.
Cada webhook de transacción exitosa incluye un objeto fee_breakdown mostrando exactamente qué comisiones se aplicaron:
types.ts
interface FeeBreakdown { total_fees: string; // Comisiones totales como string BigInt escalado fees: Array<{ fee_name: string; // Identificador de la comisión amount: string; // Monto de la comisión como string BigInt escalado rate: number; // La tasa o valor fijo utilizado }>;}
Cuando proporcionas un webhookUrl durante la creación de la tarjeta, tu endpoint recibe notificaciones POST en tiempo real para cada evento de transacción — compras, rechazos y ajustes (reembolsos).
Todos los eventos de tarjeta comparten esta estructura:
types.ts
interface CardWebhookPayload { account_urn: string; // URN de la cuenta de tarjeta transaction_id: string; // Identificador único de la transacción type: 'authorization' | 'adjustment'; direction: 'debit' | 'credit'; event: CardEventType; amount?: string; // Monto escalado como string BigInt asset?: string; // Activo utilizado (ej. "DUSD/6") local_amount?: number; // Monto en la moneda local del comercio local_currency?: string; // Código de moneda ISO 4217 (ej. "USD", "COP") exchange_rate?: number; // Tasa de conversión aplicada (1 si coincidencia directa) merchant?: MerchantInfo; medium?: TransactionMedium; fee_breakdown?: FeeBreakdown; reason?: string; // Presente en eventos de rechazo}
import express from 'express';const app = express();app.post('/webhooks/cards', express.json(), (req, res) => { const payload = req.body; console.log(`[${payload.transaction_id}] ${payload.event} — ${payload.type}/${payload.direction}`); switch (payload.event) { case 'purchase': console.log(`Compra: ${payload.local_amount} ${payload.local_currency}`); console.log(`Comercio: ${payload.merchant?.name}`); console.log(`Comisiones: ${payload.fee_breakdown?.total_fees}`); // Actualizar registros, notificar usuario, etc. break; case 'credit_adjustment': console.log(`Reembolso: ${payload.local_amount} ${payload.local_currency}`); // Procesar reembolso en tu sistema break; case 'debit_adjustment': console.log(`Ajuste de débito: ${payload.local_amount} ${payload.local_currency}`); break; case 'rejected_insufficient_funds': console.log(`Rechazado: ${payload.reason}`); // Notificar al usuario de la transacción fallida break; case 'rejected_currency': console.log(`Moneda no soportada: ${payload.currency}`); break; case 'rejected_credit': console.log(`Crédito rechazado: ${payload.reason}`); break; } res.status(200).send('OK');});
Idempotencia
La entrega de webhooks usa claves de idempotencia basadas en ${type}-${transaction_id}. Tu handler debe ser idempotente — procesar el mismo evento dos veces debe producir el mismo resultado.
Notificaciones de WhatsApp
Los eventos de compra también pueden activar notificaciones de WhatsApp al titular de la tarjeta si whatsapp_notification está habilitado en el metadata de la tarjeta y el usuario tiene un número de teléfono registrado.
En ajustes de credito (reembolsos), los recargos de cashback se revierten proporcionalmente. Un reembolso del 50% devuelve el 50% del recargo de cada programa desde los bolsillos de ahorro. No se envia un evento webhook separado para las reversiones de cashback.