Web

Todos los métodos, opciones y errores del Web SDK.

Referencia del SDK Web de Tonder (@tonder.io/web-sdk, TypeScript, tipos incluidos). La guía paso a paso está en SDK Web; el código fuente y README en github.com/tonderio/web-sdk.

import { createTonder, AppError, ErrorKeyEnum } from '@tonder.io/web-sdk';

¿Prefieres cargarlo con <script> en vez de npm? Las URLs de CDN aprobadas para stage y producción están en SDK Web → Instalación.

createTonder(config)

Crea una instancia del SDK para un comprador/sesión.

interface TonderConfig {
  api_key: string;
  environment: 'sandbox' | 'stage' | 'production';
  session?: {
    customer?: {
      email: string;
      first_name?: string;
      last_name?: string;
      phone?: string;
    };
    secure_token?: string;
  };
  presentation_mode?: 'redirect' | 'embedded';
  events?: {
    presentation?: {
      on_open?(): void;
      on_close?(): void;
    };
  };
  customization?: TonderCustomization;
}
CampoRequeridoDescripción
api_keyLlave pública de Tonder para navegador.
environment'sandbox', 'stage' o 'production'.
session.customerPara pay() y tarjetas guardadasIdentidad del cliente.
session.secure_tokenPara tarjetas guardadasToken de corta vida generado en tu backend.
presentation_modeNo'redirect' (default) o 'embedded'.
events.presentation.on_openNoSe llama al abrir la vista hosted embebida.
events.presentation.on_closeNoSe llama cuando el comprador cierra la vista embebida.
customization.card_fieldsNoPersonalización de los campos seguros (abajo).

Lanza INIT_ERROR si falta config o api_key, o si environment es inválido.

customization.card_fields

Todos los campos son opcionales; lo omitido usa los defaults del SDK.

CampoTipoDescripción
labelsCardLabelsTexto sobre cada campo seguro (cardholder_name, card_number, cvv, expiration_month, expiration_year).
placeholdersCardPlaceholdersPlaceholder dentro de cada campo seguro.
stylesCardStylesEstilos globales (card_form) y por campo para inputs, etiquetas, errores e icono de la tarjeta (enable_card_icon).
error_messagesCardFieldErrorMessagesMensajes de validación (required, invalid y por campo).

Los valores de estilo usan claves CSS-in-JS del renderizador seguro (p. ej. font_size, font_family, color, border_color). styles aplica dentro del iframe seguro; el layout del contenedor (p. ej. .card-field { max-height: 90px; }) se controla con tu propio CSS.

const tonder = createTonder({
  api_key: 'pk_test_...',
  environment: 'sandbox',
  customization: {
    card_fields: {
      labels: { card_number: 'Número de tarjeta', cvv: 'Código de seguridad' },
      placeholders: { card_number: '4111 1111 1111 1111', expiration_month: 'MM' },
      styles: {
        card_form: {
          input_styles: {
            base: { color: '#111827', font_family: 'Inter, sans-serif', font_size: '16px' },
            focus: { border_color: '#2563eb' },
            invalid: { color: '#b91c1c' },
          },
          label_styles: { base: { color: '#374151', font_weight: '600' } },
          error_styles: { base: { color: '#b91c1c' } },
        },
        enable_card_icon: true,
      },
      error_messages: { required: 'Completa este campo.', invalid: 'Revisa este campo.' },
    },
  },
});

Métodos

MétodoQué haceRequiere init()
tonder.init()Carga la configuración del comercio y prepara el SDK. Seguro llamarlo más de una vez.
tonder.create('card_fields', options?)Crea el componente de campos seguros.No
card_fields.mount()Monta los campos seguros en los contenedores.
card_fields.unmount()Desmonta los campos de este componente.No
card_fields.reveal(input)Muestra valores seguros de una tarjeta guardada (nunca el CVV).
tonder.pay(input)Crea un pago.
tonder.getTransaction(id)Lee el estado actual de una transacción.No
tonder.enrollCard()Guarda la tarjeta nueva montada para session.customer.
tonder.getCustomerCards()Lista las tarjetas guardadas del cliente.
tonder.removeCustomerCard(card_id)Elimina una tarjeta guardada.
tonder.getPaymentMethods()Lista los métodos de pago activos del negocio.No
tonder.getPaymentMethodBanks()Lista bancos SafetyPay agrupados por canal.No

tonder.create('card_fields', options?)

Sin options, el SDK monta el formulario completo de tarjeta nueva usando los contenedores por defecto:

CampoContenedor por defecto
cardholder_name#collect-cardholder-name
card_number#collect-card-number
expiration_month#collect-expiration-month
expiration_year#collect-expiration-year
cvv#collect-cvv (o #collect-cvv-<card_id> para tarjetas guardadas)
interface CardFieldsOptions {
  fields?: (CardField | { field: CardField; container_id?: string })[];
  card_id?: string; // para el CVV de una tarjeta guardada
  unmount_context?: 'all' | 'none' | 'current' | 'create' | string;
  events?: Partial<Record<CardField, {
    on_change?(state: CardFieldState): void;
    on_blur?(state: CardFieldState): void;
    on_focus?(state: CardFieldState): void;
    on_ready?(state: CardFieldState): void;
  }>>;
}

tonder.pay(input)

interface PayInput {
  amount: number;
  currency?: string;
  return_url: string;
  payment_method:
    | { type: 'card' }
    | { type: 'saved_card'; card_id: string }
    | { type: string; config?: Record<string, unknown> };
  metadata?: Record<string, unknown>;
  billing_address?: {
    street?: string;
    street2?: string;
    state?: string;
    country?: string;
    zip_code?: string;
  };
  client_reference: string;
  idempotency_key?: string;
}
CampoRequeridoDescripción
amountMonto del pago (unidades decimales). Debe ser mayor que 0.
currencyNoCódigo de moneda. MXN por defecto.
return_urlURL usada tras la autenticación hosted o el redirect.
payment_methodTarjeta nueva, tarjeta guardada o un método alternativo habilitado.
billing_addressNoDirección de facturación del comprador. Todos sus campos son opcionales.
client_referenceTu referencia de orden — aparece en dashboards, exportes, webhooks y reportes.
idempotency_keyNoLlave estable por intento de pago para que los reintentos no dupliquen cargos.
metadataNoContexto no sensible para conciliación y reportes.

Llaves de metadata con significado en reportes:

LlaveUso en reportes
operation_dateFecha/hora de operación de negocio para reportes y conciliación.
customer_emailEmail mostrado en reportes de transacciones.
customer_idIdentificador de cliente del comercio para filtrado.
business_userUsuario interno, terminal POS o automatización que originó el pago.

Devuelve Promise<RawTransaction>. Una transacción que necesita 3DS o instrucciones hosted puede incluir next_action.redirect_to_url.url; las respuestas de APM/SPEI pueden incluir clabe, bank_name, payment_instructions y voucher_pdf.

tonder.getCustomerCards()

interface Card {
  card_id: string;
  card_number: string; // enmascarado
  expiration_month: string;
  expiration_year: string;
  card_scheme: string;
  subscription_id: string | null;
}

subscription_id solo se devuelve cuando Card-on-File está habilitado para el negocio. Si es null, monta el campo CVV de la tarjeta guardada antes de llamar pay() con esa tarjeta.

tonder.getPaymentMethods()

interface PaymentMethodInfo {
  id: number;
  payment_method: string; // el valor que va en payment_method.type de pay()
  label: string;
  logo: string;
  category: string;
}

Devuelve Promise<PaymentMethodInfo[]> con los métodos alternativos activos del negocio. Úsalo para construir la lista de métodos en tu UI en vez de codificarla a mano: payment_method es el valor que después pasas como payment_method.type en pay().

[
  {
    "id": 7,
    "payment_method": "oxxopay",
    "label": "Oxxo Pay",
    "logo": "https://...",
    "category": "cash"
  }
]

tonder.getPaymentMethodBanks()

interface PaymentMethodBank {
  id: number;
  name: string;
  code: string;
  country: string;
  channel: 'WP' | 'OL'; // WP = efectivo, OL = transferencia
  logo?: string;
}

interface PaymentMethodBanks {
  cash: PaymentMethodBank[];
  transfer: PaymentMethodBank[];
}

Para safetypayCash / safetypayTransfer, arma payment_method.config con country (bank.country), channel (bank.channel) y bank_ids: [{ id: bank.code }] — el código de ruteo bancario, no el bank.id interno.

Tipos

import type {
  TonderConfig,
  PayInput,
  RawTransaction,
  Customer,
  Card,
  EnrollResult,
  PaymentMethodInfo,
  PaymentMethodBank,
  PaymentMethodBanks,
  CardFieldsOptions,
  CardFieldsComponent,
  TonderEvents,
  PresentationEvents,
} from '@tonder.io/web-sdk';

RawTransaction

pay() y getTransaction() devuelven los campos en snake_case, igual que el API y los webhooks de Tonder:

interface RawTransaction {
  id: string;
  operation_type: string;
  status: string;
  amount: number;
  currency: string;
  client_reference?: string;
  metadata?: Record<string, unknown>;
  provider?: string;
  created_at?: string;
  status_code?: number;
  next_action?: {
    redirect_to_url?: {
      url: string;
      verify_transaction_status_url?: string;
    };
  };
  decline_code?: string;
  decline_reason?: string;
  payment_instructions?: Record<string, unknown>;
  voucher_pdf?: string;
  clabe?: string;
  bank_name?: string;
  [key: string]: unknown;
}

Errores

Los fallos del SDK se lanzan como AppError. Los rechazos de pago no se lanzan: se devuelven como transacciones — lee transaction.status. Usa error.code para ramificar; no parsees error.message.

try {
  const transaction = await tonder.pay({ /* ... */ });
} catch (error) {
  if (error instanceof AppError) {
    console.error(error.code, error.status_code, error.details.system_error);
    if (error.code === ErrorKeyEnum.MISSING_CUSTOMER) {
      // Recrea el SDK con session.customer.
    }
  } else {
    throw error;
  }
}

Códigos principales:

CódigoCuándo ocurreCómo resolverlo
INIT_ERRORFalló la inicialización del SDK.Verifica api_key, environment y el acceso de red.
NOT_INITIALIZEDUn método requiere init() completado.Llama await tonder.init() antes de la operación.
MISSING_CUSTOMERFalta session.customer.Crea el SDK con session.customer.email.
SECURE_TOKEN_REQUIREDLas operaciones de tarjetas guardadas requieren session.secure_token.Genera el token en tu backend y pásalo en createTonder().
INVALID_PAYMENT_REQUESTamount, return_url, client_reference o payment_method inválidos.Valida el request antes de llamar pay().
INVALID_APM_CONFIGsafetypayCash/safetypayTransfer sin config.country, config.channel o config.bank_ids.Arma el config con el banco de getPaymentMethodBanks().
MOUNT_COLLECT_ERRORLos campos seguros no pudieron montarse o recolectar datos válidos.Verifica que los contenedores existan y los campos estén completos.
SECURE_FIELDS_LOAD_ERROREl navegador no pudo cargar los campos seguros.Revisa CSP, bloqueadores de anuncios y red.
PAYMENT_PROCESS_ERROREl pago no pudo crearse/procesarse.Inspecciona error.details y reintenta solo si es seguro/idempotente.
FETCH_TRANSACTION_ERRORFalló la consulta de la transacción.Verifica el id y reconcilia desde backend/webhooks.
POLL_TIMEOUT_ERROREl 3DS embebido terminó pero la reconciliación no llegó a un estado final a tiempo.No cumplas desde el cliente; reconcilia con getTransaction() o webhooks.
SAVE_CARD_ERROR / REMOVE_CARD_ERROR / CARD_ON_FILE_DECLINEDGuardado/eliminación/enrolamiento de tarjeta falló.Pide otra tarjeta o revisa error.details.
FETCH_PAYMENT_METHODS_ERROR / FETCH_PAYMENT_METHOD_BANKS_ERROREl catálogo de métodos/bancos no pudo recuperarse.Reintenta u ofrece códigos de método conocidos directo en pay().

La lista completa (incluidos códigos raros/de compatibilidad) está en el README del SDK.

Estados de pago

Lee el estado en transaction.status:

EstadoSignificadoQué hacer
SuccessPago completado.Confirma el pedido.
AuthorizedPago autorizado por el procesador.Continúa según tu configuración y reconcilia con webhooks.
PendingAún no es final (3DS por redirect, APM/SPEI asíncrono).Espera el webhook o consulta con getTransaction().
ProcessingEl proveedor sigue procesando.No cumplas todavía.
DeclinedEl emisor/procesador rechazó el pago.Muestra un mensaje recuperable.
FailedEl pago falló.Muestra un mensaje recuperable u ofrece otro método.
CancelledPago cancelado o anulado.No cumplas; permite iniciar un pago nuevo.
ExpiredNo se completó a tiempo.Pide al cliente iniciar un pago nuevo.

Siguientes pasos

¿Te resultó útil esta página?

En esta página