Getting Started
Ship your first payment end-to-end (server + frontend + webhook) in minutes.
Installation
Frontend (React)
Install the React components package:
npm add @bloque/payments-react
yarn add @bloque/payments-react
pnpm add @bloque/payments-react
bun add @bloque/payments-react
deno add npm:@bloque/payments-react
Backend (Node.js/Bun)
Install the backend SDK:
yarn add @bloque/payments
pnpm add @bloque/payments
deno add npm:@bloque/payments
API Keys
To use Bloque Payments, you'll need API keys. You can obtain them from the Bloque Dashboard.
Bloque uses a three-credential model:
Secret Key Security
Your secret key (sk_live_...) must never be exposed in client-side code. It should only be used on the server.
How It Works
1. Your backend creates a checkout session using @bloque/payments (secret key)
↓
2. Backend receives checkout_id + client_secret
↓
3. Pass checkout_id and client_secret to React component
↓
4. Component renders iframe with the checkout (publishable key + client secret)
↓
5. User completes payment (with 3D Secure if required)
↓
6. onSuccess/onError/onPending callbacks are triggered
7. Your webhook receives payment.status.updated for finality
Quick Start: Complete Integration (Hosted Checkout)
Here's a complete example showing how to integrate Bloque Payments with React on the frontend and Node.js/Bun on the backend.
Backend Setup (Node.js/Bun)
First, create an endpoint to generate checkout sessions:
import { Bloque } from '@bloque/payments';
import express from 'express';
const app = express();
app.use(express.json());
// Initialize Bloque SDK with your secret key
const bloque = new Bloque({
secretKey: process.env.BLOQUE_SECRET_KEY!,
mode: 'production', // or 'sandbox' for testing
});
// Checkout endpoint
app.post('/api/create-checkout', async (req, res) => {
try {
// 1) Create a checkout (payment link)
const checkout = await bloque.checkout.create({
name: 'My Product',
description: 'Product description',
items: [
{
name: 'Product',
amount: 2999, // Amount in smallest currency unit (e.g., cents)
quantity: 1,
},
],
success_url: 'https://yourapp.com/success',
});
// 2) Return checkoutId + clientSecret to the frontend
res.json({
id: checkout.id,
url: checkout.url,
clientSecret: checkout.client_secret,
});
} catch (error) {
console.error('Checkout error:', error);
res.status(500).json({
success: false,
error: error.message,
});
}
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
Frontend Setup (React)
import { init, BloqueCheckout } from '@bloque/payments-react';
// Initialize SDK (do this once at app startup)
init({
publishableKey: 'pk_live_...',
mode: 'production',
});
interface CheckoutPageProps {
checkoutId: string;
clientSecret: string;
}
function CheckoutPage({ checkoutId, clientSecret }: CheckoutPageProps) {
return (
<BloqueCheckout
checkoutId={checkoutId}
clientSecret={clientSecret}
// Optional: limit payment tabs shown in the hosted checkout UI
paymentMethods={['card', 'pse', 'cash']}
appearance={{
primaryColor: '#10b981',
borderRadius: '12px',
}}
onSuccess={(data) => {
console.log('Payment successful!', data.payment_id);
window.location.href = '/success';
}}
onPending={(data) => {
console.log('Payment pending:', data.payment_id);
// Common for PSE: treat as pending until webhook finality
}}
onError={(error) => {
console.error('Payment failed:', error);
}}
/>
);
}
export default CheckoutPage;
Webhook (Recommended)
For reliable final status (especially for asynchronous methods like PSE), set up a webhook endpoint and handle the payment.status.updated event.
See Webhooks Setup.
Environment Variables
Create a .env file in your backend project:
# .env
BLOQUE_SECRET_KEY=sk_live_your_secret_key_here
BLOQUE_WEBHOOK_SECRET=your_webhook_secret_here
And for your frontend:
# .env
NEXT_PUBLIC_BLOQUE_PUBLISHABLE_KEY=pk_live_your_publishable_key_here
Load them in your application:
import 'dotenv/config';
const bloque = new Bloque({
secretKey: process.env.BLOQUE_SECRET_KEY!,
mode: 'production',
});
Configuration Options
SDK Configuration (Backend)
* Either secretKey (recommended) or legacy accessToken is required.
Modes
sandbox: For testing and development. No real transactions. Use sk_test_ / pk_test_ keys.
production: For live operations with real payments. Use sk_live_ / pk_live_ keys.
React Component Props
When to use Direct Payments
Hosted Checkout is the recommended integration. Use Direct Payments (server-side) when you need to submit card/PSE/cash from your backend.
See Direct Payments.
Appearance Configuration
Customize the look and feel:
const appearance = {
primaryColor: '#10b981', // Brand color
borderRadius: '12px', // Border radius for inputs
fontFamily: 'Inter, system-ui, sans-serif', // Font family
};
TypeScript Support
The SDK is fully typed with TypeScript. Import types for better development experience:
import { BloqueCheckout, init } from '@bloque/payments-react';
import type {
BloqueCheckoutProps,
AppearanceConfig,
PaymentResult,
} from '@bloque/payments-react';
const handleSuccess = (result: PaymentResult) => {
console.log('Payment ID:', result.payment_id);
console.log('Status:', result.status);
};
Testing in Sandbox Mode
Use sandbox mode for testing without real transactions:
// Backend
const bloque = new Bloque({
secretKey: process.env.BLOQUE_SECRET_KEY!, // sk_test_...
mode: 'sandbox',
});
// Frontend
init({
publishableKey: 'pk_test_...',
mode: 'sandbox',
});
Test Card Numbers
Use these test card numbers in sandbox mode:
Next Steps
Now that you have basic integration working, explore more features:
Need Help?