đźš§ Bloque documentation is under development

React Integration - Basic Setup

Learn how to integrate Bloque Payments into your React application using the BloqueCheckout component.

Installation

Install the React components package:

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

How It Works

The BloqueCheckout component renders an iframe with the Bloque hosted checkout page. The flow is:

1. Your backend creates a checkout session using @bloque/payments
   ↓
2. Backend receives checkout_id
   ↓
3. Pass checkout_id to React component
   ↓
4. Component renders iframe with the checkout
   ↓
5. User completes payment
   ↓
6. onSuccess/onError/onPending callbacks are triggered

SDK Initialization

Before using the BloqueCheckout component, initialize the SDK with your Public API Key:

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

// Initialize once at the start of your application (e.g., in main.tsx or App.tsx)
init({
  publicApiKey: 'pk_live_...',
  mode: 'sandbox', // or 'production'
});
Public API Key

Use your Public API Key to initialize the SDK in the frontend. This key is safe to expose in client-side code. Your Secret API Key should only be used on the backend.

Basic Usage

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

// Initialize once at the start of your application
init({
  publicApiKey: 'pk_live_...',
  mode: 'production',
});

interface CheckoutPageProps {
  // checkoutId is generated on the backend using @bloque/payments
  checkoutId: string;
}

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

export default CheckoutPage;

Backend Setup

Create a checkout session on your backend using @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: 'My Product',
      items: [{ name: 'Product', amount: 2999, quantity: 1 }],
      success_url: 'https://yourapp.com/success',
    });

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

app.listen(3000);

Component Props

BloqueCheckout

PropTypeRequiredDescription
checkoutIdstringYesCheckout session ID from your backend
onSuccess(data: PaymentResult) => voidNoCalled when payment is successful
onError(error: string) => voidNoCalled when payment fails
onPending(data: PaymentResult) => voidNoCalled when payment is pending
onReady() => voidNoCalled when checkout iframe is ready
publicApiKeystringNoPublic API key (optional if you called init())
mode'production' | 'sandbox'NoEnvironment mode (optional if you called init())
checkoutUrlstringNoCustom checkout URL
appearanceAppearanceConfigNoUI customization
showInstallmentsbooleanNoShow installment payment options
paymentMethodsPaymentMethod[]NoPayment methods to display (default: ['card'])
iframeStylesRecord<string, string>NoCustom CSS styles for the iframe
classNamestringNoCSS class for the container div
styleReact.CSSPropertiesNoInline styles for the container div

AppearanceConfig

interface AppearanceConfig {
  primaryColor?: string;    // Brand color (e.g., '#6366f1')
  borderRadius?: string;    // Border radius (e.g., '12px')
  fontFamily?: string;      // Font family (e.g., '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';
ValueDescription
cardCredit/debit card payment
psePSE payment (bank transfer Colombia)

Examples

With Custom Appearance

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

With Specific Payment Methods

// PSE only
<BloqueCheckout
  checkoutId={checkoutId}
  paymentMethods={['pse']}
  onSuccess={(data) => {
    console.log('Payment successful!', data);
  }}
/>

// Card and PSE
<BloqueCheckout
  checkoutId={checkoutId}
  paymentMethods={['card', 'pse']}
  onSuccess={(data) => {
    console.log('Payment successful!', data);
  }}
/>

With All Callbacks

<BloqueCheckout
  checkoutId={checkoutId}
  onReady={() => {
    console.log('Checkout is ready');
  }}
  onSuccess={(data) => {
    console.log('Payment approved!', data);
    window.location.href = '/success';
  }}
  onPending={(data) => {
    console.log('Payment pending...', data);
  }}
  onError={(error) => {
    console.error('Payment failed:', error);
  }}
/>

Custom Styling

<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)',
  }}
/>

Framework-Specific Examples

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>Loading...</div>;

  return (
    <BloqueCheckout
      checkoutId={checkoutId}
      onSuccess={(data) => {
        console.log('Success!', 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>Loading...</div>;

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

TypeScript Support

The package includes full TypeScript definitions:

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

const handleSuccess = (result: PaymentResult) => {
  console.log('Payment ID:', result.payment_id);
  console.log('Amount:', result.amount);
  console.log('Currency:', result.currency);
  console.log('Status:', result.status);
};

Next Steps