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
Inicialización del SDK
Antes de usar el componente BloqueCheckout, debes inicializar 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 del Componente
La forma más simple de agregar pagos a tu app React. El componente procesa los pagos directamente con la API de Bloque:
import { init, BloqueCheckout } from '@bloque/payments-react';
// Inicializar una vez al inicio de tu aplicación
init({
publicApiKey: 'pk_live_...',
mode: 'production',
});
function CheckoutPage() {
return (
<BloqueCheckout
config={{
payment_methods: ['card', 'pse', 'cash'],
amount: 2999,
currency: 'USD',
}}
onSuccess={(response) => {
console.log('¡Pago exitoso!', response.id);
window.location.href = '/success';
}}
onError={(error) => {
console.error('Pago fallido:', error.message);
alert(`Pago fallido: ${error.message}`);
}}
/>
);
}
export default CheckoutPage;
Uso con Backend Personalizado
Si prefieres procesar los pagos a través de tu propio backend, usa la prop onSubmit:
import { BloqueCheckout } from '@bloque/payments-react';
function CheckoutPage() {
const handleSubmit = async (payload) => {
const response = await fetch('/api/payments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error('Pago fallido');
}
return response.json();
};
return (
<BloqueCheckout
config={{
payment_methods: ['card', 'pse', 'cash'],
amount: 2999,
currency: 'USD',
}}
onSubmit={handleSubmit}
onSuccess={(response) => {
console.log('¡Pago exitoso!', response.id);
window.location.href = '/success';
}}
onError={(error) => {
console.error('Pago fallido:', error.message);
alert(`Pago fallido: ${error.message}`);
}}
/>
);
}
export default CheckoutPage;
Props del Componente
Props Opcionales
onSubmit
Función llamada cuando el usuario envía el formulario de pago. Si no se proporciona, el componente procesa el pago directamente con la API de Bloque.
onSubmit?: (payload: PaymentSubmitPayload) => Promise<PaymentResponse | undefined>;
Ejemplo:
const handleSubmit = async (payload) => {
const response = await fetch('/api/payments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error('Pago fallido');
}
return response.json();
};
<BloqueCheckout onSubmit={handleSubmit} />
Props Opcionales
config
Objeto de configuración para la experiencia de checkout:
interface CheckoutConfig {
payment_methods?: PaymentMethodType[]; // ['card', 'pse', 'cash']
amount?: number; // Monto en la unidad más pequeña
currency?: string; // Código de moneda (ej: 'USD')
labels?: CheckoutLabels; // Textos personalizados
}
Ejemplo:
<BloqueCheckout
config={{
payment_methods: ['card', 'pse'],
amount: 2999,
currency: 'USD',
}}
onSubmit={handleSubmit}
/>
config.labels
Personaliza los textos del formulario de pago:
interface CheckoutLabels {
card?: CardFormLabels;
pse?: PSEFormLabels;
cash?: CashFormLabels;
}
interface CardFormLabels {
cardNumber?: string;
cardNumberPlaceholder?: string;
cardholderName?: string;
cardholderNamePlaceholder?: string;
expiryDate?: string;
expiryDatePlaceholder?: string;
cvv?: string;
cvvPlaceholder?: string;
email?: string;
emailPlaceholder?: string;
submitButton?: string;
}
Ejemplo con textos personalizados:
<BloqueCheckout
config={{
payment_methods: ['card', 'pse'],
amount: 4999,
currency: 'USD',
labels: {
card: {
cardNumber: 'Número de tarjeta',
cardNumberPlaceholder: '1234 5678 9012 3456',
cardholderName: 'Nombre del titular',
cardholderNamePlaceholder: 'JUAN PÉREZ',
expiryDate: 'Fecha de expiración',
expiryDatePlaceholder: 'MM/AA',
cvv: 'CVV',
cvvPlaceholder: '123',
email: 'Correo electrónico',
emailPlaceholder: 'ejemplo@correo.com',
submitButton: 'Pagar $49.99',
},
},
}}
onSubmit={handleSubmit}
/>
appearance
Personaliza la apariencia visual:
interface AppearanceConfig {
primaryColor?: string; // Color de marca
borderRadius?: string; // Radio de borde para inputs
fontFamily?: string; // Familia de fuente
}
Ejemplo:
<BloqueCheckout
config={config}
appearance={{
primaryColor: '#10b981',
borderRadius: '12px',
fontFamily: 'Inter, system-ui, sans-serif',
}}
onSubmit={handleSubmit}
/>
amount
Forma alternativa de establecer el monto (en lugar de usar config.amount):
<BloqueCheckout
amount={2999}
config={{
payment_methods: ['card'],
currency: 'USD',
}}
onSubmit={handleSubmit}
/>
availableMethods
Array de métodos de pago a mostrar (alternativa a config.payment_methods):
<BloqueCheckout
availableMethods={['card', 'pse']}
onSubmit={handleSubmit}
/>
requireEmail
Si el email es requerido para pagos con tarjeta (predeterminado: true):
<BloqueCheckout
requireEmail={true}
config={{ payment_methods: ['card'] }}
onSubmit={handleSubmit}
/>
showMethodSelector
Mostrar/ocultar el selector de método de pago (predeterminado: true):
<BloqueCheckout
showMethodSelector={true}
config={{ payment_methods: ['card', 'pse'] }}
onSubmit={handleSubmit}
/>
onSuccess
Callback disparado cuando el pago tiene éxito:
<BloqueCheckout
config={config}
onSubmit={handleSubmit}
onSuccess={(response) => {
console.log('¡Pago exitoso!');
console.log('ID de Pago:', response.id);
console.log('Estado:', response.status);
window.location.href = '/success';
}}
/>
onError
Callback disparado cuando el pago falla:
<BloqueCheckout
config={config}
onSubmit={handleSubmit}
onError={(error) => {
console.error('Pago fallido:', error.message);
alert(`Pago fallido: ${error.message}`);
}}
/>
className y style
Props estándar de React para estilos:
<BloqueCheckout
config={config}
onSubmit={handleSubmit}
className="my-checkout"
style={{ maxWidth: '600px', margin: '0 auto' }}
/>
Ejemplo Completo
Aquí hay un ejemplo completo con todas las opciones comunes:
import { BloqueCheckout } from '@bloque/payments-react';
import type {
CheckoutConfig,
AppearanceConfig,
PaymentResponse,
} from '@bloque/payments-react';
function CheckoutPage() {
// Configuración
const config: CheckoutConfig = {
payment_methods: ['card', 'pse', 'cash'],
amount: 2999,
currency: 'USD',
};
// Apariencia
const appearance: AppearanceConfig = {
primaryColor: '#10b981',
borderRadius: '12px',
fontFamily: 'Inter, system-ui, sans-serif',
};
// Manejador de envío
const handleSubmit = async (payload) => {
try {
const response = await fetch('/api/payments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Pago fallido');
}
return response.json();
} catch (error) {
console.error('Error de pago:', error);
throw error;
}
};
// Manejador de éxito
const handleSuccess = (response: PaymentResponse) => {
console.log('¡Pago exitoso!');
console.log('ID de Pago:', response.id);
console.log('Estado:', response.status);
window.location.href = `/success?payment=${response.id}`;
};
// Manejador de error
const handleError = (error: { message: string }) => {
console.error('Pago fallido:', error.message);
alert(`Pago fallido: ${error.message}`);
};
return (
<div className="checkout-container">
<h1>Checkout</h1>
<BloqueCheckout
config={config}
appearance={appearance}
onSubmit={handleSubmit}
onSuccess={handleSuccess}
onError={handleError}
className="checkout-form"
style={{ maxWidth: '600px' }}
/>
</div>
);
}
export default CheckoutPage;
Soporte TypeScript
El paquete incluye definiciones completas de TypeScript:
import type {
BloqueCheckoutProps,
CheckoutConfig,
AppearanceConfig,
PaymentResponse,
PaymentSubmitPayload,
PaymentMethodType,
} from '@bloque/payments-react';
// Configuración type-safe
const config: CheckoutConfig = {
payment_methods: ['card', 'pse'],
amount: 2999,
currency: 'USD',
};
// Manejadores type-safe
const handleSuccess = (response: PaymentResponse) => {
console.log('ID de Pago:', response.id);
};
Ejemplos Específicos por Framework
Next.js App Router
'use client';
import { BloqueCheckout } from '@bloque/payments-react';
export default function CheckoutPage() {
const handleSubmit = async (payload) => {
const response = await fetch('/api/payments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
return response.json();
};
return (
<BloqueCheckout
config={{
payment_methods: ['card', 'pse'],
amount: 2999,
currency: 'USD',
}}
onSubmit={handleSubmit}
/>
);
}
Next.js Pages Router
import { BloqueCheckout } from '@bloque/payments-react';
export default function Checkout() {
const handleSubmit = async (payload) => {
const response = await fetch('/api/payments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
return response.json();
};
return (
<BloqueCheckout
config={{
payment_methods: ['card'],
amount: 2999,
currency: 'USD',
}}
onSubmit={handleSubmit}
/>
);
}
Vite + React
import { BloqueCheckout } from '@bloque/payments-react';
function App() {
const handleSubmit = async (payload) => {
const response = await fetch('http://localhost:3000/api/payments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
return response.json();
};
return (
<BloqueCheckout
config={{
payment_methods: ['card', 'pse', 'cash'],
amount: 2999,
currency: 'USD',
}}
onSubmit={handleSubmit}
/>
);
}
export default App;
Próximos Pasos