Backend SDK Examples
Explore practical, production-ready examples for integrating the ProBuy Backend SDK in various Node.js frameworks. All examples include proper error handling, TypeScript support, and best practices.
Example 1: Express.js Server
Complete Express.js integration with ProBuy Backend SDK, including health checks, checkout creation, and status endpoints.
/** * Express Server with ProBuy Backend SDK * Complete integration example with proper error handling */
import express from 'express';import cors from 'cors';import { ProBuyBackendSDK, ProBuyError } from '@probuy/backend-sdk';
const app = express();const PORT = process.env.PORT || 3001;
// Middlewareapp.use(cors());app.use(express.json());
// Initialize ProBuy SDKconst probuy = new ProBuyBackendSDK({ apiToken: process.env.PROBUY_API_TOKEN || 'your-api-token-here', environment: process.env.PROBUY_ENVIRONMENT || 'sandbox', debug: process.env.NODE_ENV !== 'production'});
console.log('๐ ProBuy SDK initialized');console.log(' Environment:', probuy.getEnvironment());console.log(' Base URL:', probuy.getBaseUrl());
// Health check endpointapp.get('/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString(), environment: probuy.getEnvironment() });});
// Create checkout sessionapp.post('/api/checkout/create', async (req, res) => { try { console.log('๐ Creating checkout session...');
const session = await probuy.createCheckoutSession(req.body);
console.log('โ
Checkout created:', session.checkout_id);
res.json({ success: true, data: session });
} catch (error) { console.error('โ Checkout creation failed:', error.message);
const statusCode = error instanceof ProBuyError && error.statusCode ? error.statusCode : 500;
res.status(statusCode).json({ success: false, error: error.message, code: error.code, details: error.details }); }});
// Create checkout with redirect URLapp.post('/api/checkout/redirect', async (req, res) => { try { console.log('๐ Creating checkout with redirect URL...');
const result = await probuy.createCheckoutWithRedirectUrl(req.body);
console.log('โ
Checkout created:', result.checkout_id); console.log(' Redirect URL:', result.redirect_url);
res.json({ success: true, data: result });
} catch (error) { console.error('โ Checkout creation failed:', error.message);
const statusCode = error instanceof ProBuyError && error.statusCode ? error.statusCode : 500;
res.status(statusCode).json({ success: false, error: error.message }); }});
// Get checkout detailsapp.get('/api/checkout/:checkoutId', async (req, res) => { try { const { checkoutId } = req.params;
console.log('๐ Fetching checkout details:', checkoutId);
const details = await probuy.getCheckoutDetails(checkoutId);
console.log('โ
Details retrieved for:', checkoutId);
res.json({ success: true, data: details });
} catch (error) { console.error('โ Failed to fetch details:', error.message);
const statusCode = error instanceof ProBuyError && error.statusCode ? error.statusCode : 500;
res.status(statusCode).json({ success: false, error: error.message }); }});
// Error handling middlewareapp.use((err, req, res, next) => { console.error('Unhandled error:', err);
res.status(500).json({ success: false, error: 'Internal server error', message: process.env.NODE_ENV === 'development' ? err.message : undefined });});
// 404 handlerapp.use((req, res) => { res.status(404).json({ success: false, error: 'Endpoint not found' });});
// Start serverapp.listen(PORT, () => { console.log(''); console.log('='.repeat(50)); console.log('๐ ProBuy Payment Server'); console.log('='.repeat(50)); console.log(`๐ก Server running on: http://localhost:${PORT}`); console.log(`๐ Environment: ${probuy.getEnvironment()}`); console.log(''); console.log('Available endpoints:'); console.log(' GET /health - Health check'); console.log(' POST /api/checkout/create - Create checkout session'); console.log(' POST /api/checkout/redirect - Create checkout with redirect URL'); console.log(' GET /api/checkout/:id - Get checkout details'); console.log('='.repeat(50)); console.log('');});
// Graceful shutdownprocess.on('SIGTERM', () => { console.log('SIGTERM received, shutting down gracefully...'); process.exit(0);});
process.on('SIGINT', () => { console.log('\nSIGINT received, shutting down gracefully...'); process.exit(0);});Example 2: NestJS Service
Professional NestJS integration with dependency injection and proper error handling.
import { Injectable, BadRequestException, UnauthorizedException, ServiceUnavailableException, InternalServerErrorException} from '@nestjs/common';import { ConfigService } from '@nestjs/config';import { ProBuyBackendSDK, CheckoutOrderData, CheckoutSessionResponse, CheckoutDetailedResponse, ProBuyError, ProBuyValidationError, ProBuyAuthenticationError} from '@probuy/backend-sdk';
@Injectable()export class PaymentService { private probuy: ProBuyBackendSDK;
constructor(private config: ConfigService) { this.probuy = new ProBuyBackendSDK({ apiToken: this.config.get<string>('PROBUY_API_TOKEN'), environment: this.config.get<string>('PROBUY_ENVIRONMENT') || 'sandbox', debug: this.config.get<string>('NODE_ENV') !== 'production' });
console.log('ProBuy SDK initialized in', this.probuy.getEnvironment()); }
/** * Create a new checkout session */ async createCheckout( orderData: CheckoutOrderData ): Promise<CheckoutSessionResponse> { try { const session = await this.probuy.createCheckoutSession(orderData); return session; } catch (error) { this.handleProBuyError(error); } }
/** * Create checkout and get redirect URL */ async createCheckoutWithRedirect( orderData: CheckoutOrderData ): Promise<CheckoutSessionResponse & { redirect_url: string }> { try { return await this.probuy.createCheckoutWithRedirectUrl(orderData); } catch (error) { this.handleProBuyError(error); } }
/** * Get checkout session details */ async getCheckoutStatus( checkoutId: string ): Promise<CheckoutDetailedResponse> { try { return await this.probuy.getCheckoutDetails(checkoutId); } catch (error) { this.handleProBuyError(error); } }
/** * Get checkout URL for customer redirection */ getCheckoutUrl(checkoutId: string): string { return this.probuy.getCheckoutUrl(checkoutId); }
/** * Centralized error handling */ private handleProBuyError(error: any): never { if (error instanceof ProBuyValidationError) { throw new BadRequestException({ message: 'Invalid order data', details: error.details }); } else if (error instanceof ProBuyAuthenticationError) { throw new UnauthorizedException('Payment service authentication failed'); } else if (error instanceof ProBuyError) { throw new ServiceUnavailableException({ message: 'Payment service error', statusCode: error.statusCode }); }
throw new InternalServerErrorException('An unexpected error occurred'); }}
// Controllerimport { Controller, Post, Get, Body, Param } from '@nestjs/common';
@Controller('checkout')export class CheckoutController { constructor(private readonly paymentService: PaymentService) {}
@Post('create') async createCheckout(@Body() orderData: CheckoutOrderData) { const session = await this.paymentService.createCheckoutWithRedirect( orderData );
return { success: true, checkout_id: session.checkout_id, redirect_url: session.redirect_url, expires_at: session.expires_at }; }
@Get(':id') async getCheckoutStatus(@Param('id') checkoutId: string) { const details = await this.paymentService.getCheckoutStatus(checkoutId);
return { success: true, data: details }; }}Example 3: Fastify Integration
High-performance Fastify server with ProBuy SDK integration and schema validation.
import Fastify from 'fastify';import { ProBuyBackendSDK } from '@probuy/backend-sdk';
const fastify = Fastify({ logger: { level: 'info', prettyPrint: process.env.NODE_ENV !== 'production' }});
// Initialize ProBuy SDKconst probuy = new ProBuyBackendSDK({ apiToken: process.env.PROBUY_API_TOKEN, environment: process.env.PROBUY_ENVIRONMENT || 'sandbox', debug: true});
// Health check routefastify.get('/health', async (request, reply) => { return { status: 'ok', environment: probuy.getEnvironment(), timestamp: new Date().toISOString() };});
// Create checkout schemaconst createCheckoutSchema = { body: { type: 'object', required: [ 'order_reference_id', 'order_number', 'currency', 'total_amount', 'consumer', 'country_code', 'merchant_url', 'billing_address', 'item' ], properties: { order_reference_id: { type: 'string' }, order_number: { type: 'string' }, currency: { type: 'string' }, total_amount: { type: 'number' }, consumer: { type: 'object', required: ['email', 'first_name', 'last_name', 'phone_number'], properties: { email: { type: 'string', format: 'email' }, first_name: { type: 'string' }, last_name: { type: 'string' }, phone_number: { type: 'string' } } } } }};
// Create checkout endpointfastify.post('/checkout/create', { schema: createCheckoutSchema}, async (request, reply) => { try { const session = await probuy.createCheckoutWithRedirectUrl(request.body);
return { success: true, data: session }; } catch (error) { fastify.log.error('Checkout creation error:', error);
reply.code(error.statusCode || 500); return { success: false, error: error.message, code: error.code }; }});
// Get checkout details endpointfastify.get('/checkout/:id', async (request, reply) => { try { const { id } = request.params; const details = await probuy.getCheckoutDetails(id);
return { success: true, data: details }; } catch (error) { reply.code(error.statusCode || 500); return { success: false, error: error.message }; }});
// Error handlerfastify.setErrorHandler((error, request, reply) => { fastify.log.error(error);
reply.status(error.statusCode || 500).send({ success: false, error: error.message || 'Internal Server Error' });});
// Start serverconst start = async () => { try { await fastify.listen({ port: 3000, host: '0.0.0.0' }); console.log('๐ Fastify server running on http://localhost:3000'); console.log('Environment:', probuy.getEnvironment()); } catch (err) { fastify.log.error(err); process.exit(1); }};
start();Example 4: Basic Usage
Simple standalone script demonstrating all SDK methods and features.
/** * Basic Usage Example * Simple example showing how to use ProBuy Backend SDK */
import { ProBuyBackendSDK } from '@probuy/backend-sdk';
// Initialize SDKconst probuy = new ProBuyBackendSDK({ apiToken: process.env.PROBUY_API_TOKEN || 'your-api-token-here', environment: 'sandbox', // 'sandbox' or 'prod' debug: true});
// Example order dataconst orderData = { order_reference_id: `ref-${Date.now()}`, order_number: `ORD-${Date.now()}`, currency: 'SAR', total_amount: 1000, shipping_amount: 0, tax_amount: 150,
item: { name: 'MacBook Pro 16-inch', description: 'Apple M2 Pro chip with powerful performance', type: 'Physical', reference_id: 'prod-123', sku: 'MBPRO-16-M2', quantity: 1, discount_amount: 0, tax_amount: 150, unit_price: 1000, total_amount: 1000 },
consumer: { first_name: 'Ahmed', last_name: 'Ali', phone_number: '+966501234567' },
country_code: 'SA', description: 'Test order from SDK example',
merchant_url: { cancel: 'https://yoursite.com/cancel', failure: 'https://yoursite.com/failure', success: 'https://yoursite.com/success' },
billing_address: { city: 'Riyadh', country_code: 'SA', first_name: 'Ahmed', last_name: 'Ali', line1: '123 King Fahd Road', line2: 'Apt 456', phone_number: '+966501234567', region: 'Riyadh' },
shipping_address: { city: 'Riyadh', country_code: 'SA', first_name: 'Ahmed', last_name: 'Ali', line1: '123 King Fahd Road', line2: 'Apt 456', phone_number: '+966501234567', region: 'Riyadh' },
platform: 'Node.js SDK Example', locale: 'en_US'};
async function main() { try { console.log('='.repeat(50)); console.log('ProBuy Backend SDK - Basic Example'); console.log('='.repeat(50)); console.log('');
// Method 1: Create checkout session console.log('1. Creating checkout session...'); const session = await probuy.createCheckoutSession(orderData);
console.log('โ
Session created successfully!'); console.log(' Checkout ID:', session.checkout_id); console.log(' Order Reference:', session.order_reference_id); console.log(' Status:', session.status); console.log(' Expires at:', session.expires_at); console.log('');
// Method 2: Get checkout URL console.log('2. Getting checkout URL...'); const checkoutUrl = probuy.getCheckoutUrl(session.checkout_id); console.log('โ
Checkout URL:', checkoutUrl); console.log('');
// Method 3: Get checkout details console.log('3. Fetching checkout details...'); const details = await probuy.getCheckoutDetails(session.checkout_id); console.log('โ
Checkout details retrieved:'); console.log(' Status:', details.status); console.log(' Total Amount:', details.total_amount, details.currency); console.log(' Customer:', details.consumer.first_name, details.consumer.last_name); console.log('');
// Method 4: Convenience method (create + get URL) console.log('4. Using convenience method...'); const result = await probuy.createCheckoutWithRedirectUrl(orderData); console.log('โ
One-step checkout creation:'); console.log(' Checkout ID:', result.checkout_id); console.log(' Redirect URL:', result.redirect_url); console.log('');
console.log('='.repeat(50)); console.log('Example completed successfully!'); console.log('='.repeat(50));
} catch (error) { console.error(''); console.error('โ Error:', error.name); console.error(' Message:', error.message); if (error.statusCode) { console.error(' Status Code:', error.statusCode); } if (error.details) { console.error(' Details:', JSON.stringify(error.details, null, 2)); } process.exit(1); }}
// Run examplemain();Example 5: Unified Checkout Integration Pattern
Real-world pattern for integrating ProBuy into a custom checkout orchestration service.
import express from 'express';import { ProBuyBackendSDK } from '@probuy/backend-sdk';
const app = express();app.use(express.json());
const probuy = new ProBuyBackendSDK({ apiToken: process.env.PROBUY_API_TOKEN, environment: process.env.PROBUY_ENVIRONMENT || 'sandbox',});
// Unified checkout flowapp.post('/checkout/initiate', async (req, res) => { try { const { cart, customer, shippingAddress } = req.body;
// Calculate totals const subtotal = cart.items.reduce( (sum, item) => sum + item.price * item.quantity, 0 ); const taxRate = 0.15; // 15% VAT const taxAmount = Math.round(subtotal * taxRate); const shippingCost = calculateShipping(shippingAddress); const totalAmount = subtotal + taxAmount + shippingCost;
// Build order data const orderData = { order_reference_id: generateOrderRef(), order_number: generateOrderNumber(), currency: 'SAR', total_amount: totalAmount, shipping_amount: shippingCost, tax_amount: taxAmount,
// For multiple items, create combined item item: { name: `Order with ${cart.items.length} items`, description: cart.items.map(i => `${i.quantity}x ${i.name}`).join(', '), type: 'Physical', reference_id: cart.id, sku: 'CART-COMBINED', quantity: 1, unit_price: subtotal, tax_amount: taxAmount, discount_amount: cart.discount || 0, total_amount: subtotal },
consumer: { email: customer.email, first_name: customer.firstName, last_name: customer.lastName, phone_number: customer.phone },
country_code: shippingAddress.countryCode,
merchant_url: { success: `${process.env.SITE_URL}/checkout/success`, failure: `${process.env.SITE_URL}/checkout/failure`, cancel: `${process.env.SITE_URL}/cart` },
billing_address: customer.billingAddress, shipping_address: shippingAddress,
additional_data: { cart_id: cart.id, items: cart.items, customer_id: customer.id } };
// Create checkout session const session = await probuy.createCheckoutWithRedirectUrl(orderData);
// Save order to database (your implementation) await saveOrder({ orderId: orderData.order_reference_id, checkoutId: session.checkout_id, customerId: customer.id, status: 'pending', total: totalAmount, items: cart.items });
// Return redirect URL to frontend res.json({ success: true, checkout_id: session.checkout_id, redirect_url: session.redirect_url });
} catch (error) { console.error('Checkout initiation error:', error); res.status(500).json({ success: false, error: 'Failed to initiate checkout' }); }});
// Success callback handlerapp.get('/checkout/success', async (req, res) => { try { const { checkout_id } = req.query;
// Get checkout details const details = await probuy.getCheckoutDetails(checkout_id);
// Update order status in your database await updateOrderStatus(details.order_number, 'completed');
// Redirect to order confirmation page res.redirect(`/order-confirmation?order=${details.order_number}`);
} catch (error) { console.error('Success callback error:', error); res.redirect('/checkout/error'); }});
// Helper functionsfunction generateOrderRef() { return `ref-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;}
function generateOrderNumber() { return `ORD-${Date.now()}`;}
function calculateShipping(address) { // Your shipping calculation logic return address.city === 'Riyadh' ? 20 : 50;}
async function saveOrder(orderData) { // Save order to your database console.log('Saving order:', orderData);}
async function updateOrderStatus(orderNumber, status) { // Update order status in your database console.log('Updating order:', orderNumber, status);}
app.listen(3000, () => { console.log('Checkout orchestrator running on port 3000');});Error Handling Best Practices
Comprehensive Error Handling
Always implement proper error handling for production applications:
import { ProBuyError, ProBuyValidationError, ProBuyAuthenticationError, ProBuyNetworkError, ProBuyApiError} from '@probuy/backend-sdk';
async function createCheckoutSafely(orderData) { try { const session = await probuy.createCheckoutSession(orderData); return { success: true, data: session };
} catch (error) { // Log error for debugging console.error('Checkout creation error:', { name: error.name, message: error.message, code: error.code, statusCode: error.statusCode });
// Handle specific error types if (error instanceof ProBuyValidationError) { return { success: false, error: 'Invalid order data', details: error.details, userMessage: 'Please check your order information and try again.' }; }
if (error instanceof ProBuyAuthenticationError) { // Alert development team notifyTeam('ProBuy authentication failure'); return { success: false, error: 'Authentication failed', userMessage: 'Payment service is temporarily unavailable.' }; }
if (error instanceof ProBuyNetworkError) { return { success: false, error: 'Network error', userMessage: 'Connection failed. Please check your internet and try again.' }; }
if (error instanceof ProBuyApiError) { return { success: false, error: 'API error', statusCode: error.statusCode, userMessage: 'Payment service error. Please try again later.' }; }
// Unknown error return { success: false, error: 'Unknown error', userMessage: 'An unexpected error occurred. Please try again.' }; }}Next Steps
โ Back to SDK Documentation
Return to the main Backend SDK documentation
Testing Guide โ
Learn how to thoroughly test your integration
Need Help?
If you need help with implementation or have questions:
- ๐ง Email: [email protected]
- ๐ฌ Contact your account manager for technical support
- ๐ Report issues on GitHub