🚧 La documentacion de Bloque está en desarrollo

Integración React - Configuración Básica

Aprende cómo integrar Bloque Payments en tu aplicación React usando el componente BloqueCheckout.

Instalación

Instala el paquete de componentes React:

npm install @bloque/payments-react
# o
yarn add @bloque/payments-react
# o
pnpm add @bloque/payments-react
# o
bun add @bloque/payments-react

Cómo Funciona

El componente BloqueCheckout renderiza un iframe con la página de checkout alojada de Bloque. El flujo es:

1. Tu backend crea una sesión de checkout usando @bloque/payments

2. Backend recibe checkout_id

3. Pasa checkout_id al componente React

4. El componente renderiza iframe con el checkout

5. Usuario completa el pago

6. Se disparan callbacks onSuccess/onError/onPending

Inicialización del SDK

Antes de usar el componente BloqueCheckout, inicializa el SDK con tu Public API Key:

import { init } from '@bloque/payments-react';

// Inicializar una vez al inicio de tu aplicación (ej: en main.tsx o App.tsx)
init({
  publicApiKey: 'pk_live_...',
  mode: 'sandbox', // o 'production'
});
Public API Key

Usa tu Public API Key para inicializar el SDK en el frontend. Esta clave es segura para exponer en código del lado del cliente. Tu Secret API Key solo debe usarse en el backend.

Uso Básico

import { init, BloqueCheckout } from '@bloque/payments-react';

// Inicializar una vez al inicio de tu aplicación
init({
  publicApiKey: 'pk_live_...',
  mode: 'production',
});

interface CheckoutPageProps {
  // El checkoutId se genera en el backend usando @bloque/payments
  checkoutId: string;
}

function CheckoutPage({ checkoutId }: CheckoutPageProps) {
  return (
    <BloqueCheckout
      checkoutId={checkoutId}
      onSuccess={(data) => {
        console.log('¡Pago exitoso!', data.payment_id);
        window.location.href = '/success';
      }}
      onError={(error) => {
        console.error('Pago fallido:', error);
      }}
    />
  );
}

export default CheckoutPage;

Configuración del Backend

Crea una sesión de checkout en tu backend usando @bloque/payments:

import { Bloque } from '@bloque/payments';
import express from 'express';

const app = express();
app.use(express.json());

const bloque = new Bloque({
  accessToken: process.env.BLOQUE_ACCESS_TOKEN!,
  mode: 'production',
});

app.post('/api/create-checkout', async (req, res) => {
  try {
    const checkout = await bloque.checkout.create({
      name: 'Mi Producto',
      items: [{ name: 'Producto', amount: 2999, quantity: 1 }],
      success_url: 'https://tuapp.com/success',
    });

    res.json({ id: checkout.id });
  } catch (error) {
    console.error('Error creando checkout:', error);
    res.status(500).json({ error: error.message });
  }
});

app.listen(3000);

Props del Componente

BloqueCheckout

PropTipoRequeridoDescripción
checkoutIdstringID de sesión de checkout de tu backend
onSuccess(data: PaymentResult) => voidNoLlamado cuando el pago es exitoso
onError(error: string) => voidNoLlamado cuando el pago falla
onPending(data: PaymentResult) => voidNoLlamado cuando el pago está pendiente
onReady() => voidNoLlamado cuando el iframe del checkout está listo
publicApiKeystringNoPublic API key (opcional si llamaste init())
mode'production' | 'sandbox'NoModo de entorno (opcional si llamaste init())
checkoutUrlstringNoURL de checkout personalizada
appearanceAppearanceConfigNoPersonalización de UI
showInstallmentsbooleanNoMostrar opciones de pago en cuotas
paymentMethodsPaymentMethod[]NoMétodos de pago a mostrar (default: ['card'])
iframeStylesRecord<string, string>NoEstilos CSS personalizados para el iframe
classNamestringNoClase CSS para el div contenedor
styleReact.CSSPropertiesNoEstilos inline para el div contenedor

AppearanceConfig

interface AppearanceConfig {
  primaryColor?: string;    // Color de marca (ej: '#6366f1')
  borderRadius?: string;    // Radio de borde (ej: '12px')
  fontFamily?: string;      // Familia de fuente (ej: 'Inter, system-ui, sans-serif')
}

PaymentResult

interface PaymentResult {
  payment_id: string;
  status: 'approved' | 'pending' | 'rejected';
  message: string;
  amount: number;
  currency: string;
  reference: string;
  created_at: string;
}

PaymentMethod

type PaymentMethod = 'card' | 'pse';
ValorDescripción
cardPago con tarjeta de crédito/débito
psePago por PSE (transferencia bancaria Colombia)

Ejemplos

Con Apariencia Personalizada

<BloqueCheckout
  checkoutId={checkoutId}
  appearance={{
    primaryColor: '#10b981',
    borderRadius: '12px',
    fontFamily: 'Inter, system-ui, sans-serif',
  }}
  onSuccess={(data) => {
    console.log('¡Pago exitoso!', data);
  }}
/>

Con Métodos de Pago Específicos

// Solo PSE
<BloqueCheckout
  checkoutId={checkoutId}
  paymentMethods={['pse']}
  onSuccess={(data) => {
    console.log('¡Pago exitoso!', data);
  }}
/>

// Tarjeta y PSE
<BloqueCheckout
  checkoutId={checkoutId}
  paymentMethods={['card', 'pse']}
  onSuccess={(data) => {
    console.log('¡Pago exitoso!', data);
  }}
/>

Con Todos los Callbacks

<BloqueCheckout
  checkoutId={checkoutId}
  onReady={() => {
    console.log('Checkout está listo');
  }}
  onSuccess={(data) => {
    console.log('¡Pago aprobado!', data);
    window.location.href = '/success';
  }}
  onPending={(data) => {
    console.log('Pago pendiente...', data);
  }}
  onError={(error) => {
    console.error('Pago fallido:', error);
  }}
/>

Estilos Personalizados

<BloqueCheckout
  checkoutId={checkoutId}
  onSuccess={handleSuccess}
  className="my-checkout"
  style={{
    maxWidth: '600px',
    margin: '0 auto',
    padding: '20px',
  }}
  iframeStyles={{
    height: '700px',
    borderRadius: '16px',
    boxShadow: '0 10px 25px rgba(0, 0, 0, 0.1)',
  }}
/>

Ejemplos Específicos por Framework

Next.js App Router

'use client';

import { init, BloqueCheckout } from '@bloque/payments-react';
import { useState, useEffect } from 'react';

init({
  publicApiKey: 'pk_live_...',
  mode: 'production',
});

export default function CheckoutPage() {
  const [checkoutId, setCheckoutId] = useState<string | null>(null);

  useEffect(() => {
    fetch('/api/create-checkout', {
      method: 'POST',
      body: JSON.stringify({ amount: 5000 }),
    })
      .then(res => res.json())
      .then(data => setCheckoutId(data.id));
  }, []);

  if (!checkoutId) return <div>Cargando...</div>;

  return (
    <BloqueCheckout
      checkoutId={checkoutId}
      onSuccess={(data) => {
        console.log('¡Éxito!', data);
      }}
    />
  );
}

Next.js Pages Router

import { init, BloqueCheckout } from '@bloque/payments-react';
import { useState, useEffect } from 'react';

init({
  publicApiKey: 'pk_live_...',
  mode: 'production',
});

export default function CheckoutPage() {
  const [checkoutId, setCheckoutId] = useState<string | null>(null);

  useEffect(() => {
    fetch('/api/create-checkout', {
      method: 'POST',
      body: JSON.stringify({ amount: 5000 }),
    })
      .then(res => res.json())
      .then(data => setCheckoutId(data.id));
  }, []);

  if (!checkoutId) return <div>Cargando...</div>;

  return (
    <BloqueCheckout
      checkoutId={checkoutId}
      onSuccess={(data) => {
        console.log('¡Éxito!', data);
      }}
    />
  );
}

Soporte TypeScript

El paquete incluye definiciones completas de TypeScript:

import { BloqueCheckout, init } from '@bloque/payments-react';
import type {
  BloqueCheckoutProps,
  AppearanceConfig,
  PaymentMethod,
  PaymentResult,
} from '@bloque/payments-react';

const handleSuccess = (result: PaymentResult) => {
  console.log('ID de Pago:', result.payment_id);
  console.log('Monto:', result.amount);
  console.log('Moneda:', result.currency);
  console.log('Estado:', result.status);
};

Próximos Pasos