Skip to main content
Version: 1.0.0

Environment Configuration

RBIH provides separate sandbox and production environments to support development, testing, and live operations. This guide covers the configuration differences and best practices for each environment.

Environment Overview

AspectSandboxProduction
PurposeDevelopment & TestingLive Operations
Token Validity6 hours12 hours
Rate LimitsLower limits for testingHigher limits for operations
DataMock/Test dataReal/Live data
MonitoringBasic loggingComprehensive monitoring
SLANo SLA guarantees99.9% uptime SLA

Sandbox Environment

Configuration

const sandboxConfig = {
baseUrl: 'https://sandbox.rbihapis.com',
authUrl: 'https://auth.nonprod.rbihub.io',
devPortal: 'https://am.nonprod.rbihub.io/devportal',

// Token settings
tokenValidity: 6 * 60 * 60, // 6 hours
refreshBuffer: 5 * 60, // 5 minutes before expiry

// Rate limits (requests per minute)
rateLimits: {
global: 100,
identity: 50,
financial: 30,
landRecords: 25,
agricultural: 5
},

// Security settings
security: {
tlsVersion: '1.3',
certificateValidation: 'strict',
ipWhitelisting: true
},

// Retry settings
retry: {
maxAttempts: 3,
baseDelay: 1000,
maxDelay: 10000
},

// Logging
logging: {
level: 'debug',
includeHeaders: true,
includePayload: true // Only in sandbox
}
};

Sandbox-Specific Features

Test Data Support

const sandboxTestData = {
// Valid test PAN numbers
validPANs: [
'ABCDE1234F',
'XYZAB5678C',
'TESTPAN123'
],

// Valid test Aadhaar numbers (masked)
validAadhaar: [
'XXXX-XXXX-1234',
'XXXX-XXXX-5678'
],

// Test mobile numbers
validMobile: [
'9876543210',
'8765432109'
],

// Test bank accounts
validAccounts: [
{
accountNumber: '1234567890',
ifsc: 'HDFC0000001',
holderName: 'Test User'
}
]
};

Mock Responses

class SandboxClient {
constructor(config) {
this.config = config;
this.mockMode = config.enableMocks || false;
}

async verifyPAN(panNumber) {
if (this.mockMode && this.isTestPAN(panNumber)) {
return this.getMockPANResponse(panNumber);
}

return this.makeRealRequest('/pan/verify', { panNumber });
}

isTestPAN(panNumber) {
return sandboxTestData.validPANs.includes(panNumber);
}

getMockPANResponse(panNumber) {
return {
success: true,
data: {
panNumber: panNumber,
name: 'Test User Name',
isValid: true,
category: 'Individual',
lastUpdated: new Date().toISOString()
},
mockResponse: true
};
}
}

Production Environment

Configuration

const productionConfig = {
baseUrl: 'https://api.rbihapis.com',
authUrl: 'https://auth.api.rbihub.io',
devPortal: 'https://am.api.rbihub.io/devportal',

// Token settings
tokenValidity: 12 * 60 * 60, // 12 hours
refreshBuffer: 30 * 60, // 30 minutes before expiry

// Rate limits (requests per minute)
rateLimits: {
global: 1000,
identity: 500,
financial: 300,
landRecords: 150,
agricultural: 25
},

// Security settings
security: {
tlsVersion: '1.3',
certificateValidation: 'strict',
ipWhitelisting: true,
additionalHeaders: {
'X-Environment': 'production',
'X-Client-Version': '1.0.0'
}
},

// Retry settings
retry: {
maxAttempts: 1, // Conservative in production
baseDelay: 2000,
maxDelay: 30000
},

// Logging
logging: {
level: 'error',
includeHeaders: false,
includePayload: false, // Never log sensitive data
auditOnly: true
},

// Monitoring
monitoring: {
healthCheck: true,
metrics: true,
alerting: true
}
};

Production-Specific Features

Enhanced Security

class ProductionSecurityManager {
constructor() {
this.sensitiveFields = [
'aadhaarNumber', 'panNumber', 'mobileNumber',
'accountNumber', 'ifsc', 'documentImage'
];
}

sanitizeForLogging(data) {
const sanitized = { ...data };

this.sensitiveFields.forEach(field => {
if (sanitized[field]) {
sanitized[field] = '[REDACTED]';
}
});

return sanitized;
}

validateProductionRequest(request) {
// Additional validation for production
if (!request.headers['X-Client-Version']) {
throw new Error('Client version header required in production');
}

if (!this.isValidClientVersion(request.headers['X-Client-Version'])) {
throw new Error('Unsupported client version');
}
}

isValidClientVersion(version) {
const supportedVersions = ['1.0.0', '1.1.0', '1.2.0'];
return supportedVersions.includes(version);
}
}

Environment-Aware Client

Configuration Management

class RBIHEnvironmentClient {
constructor(environment = 'sandbox') {
this.environment = environment;
this.config = this.getEnvironmentConfig(environment);
this.securityManager = new ProductionSecurityManager();
}

getEnvironmentConfig(env) {
const configs = {
sandbox: sandboxConfig,
production: productionConfig
};

if (!configs[env]) {
throw new Error(`Unknown environment: ${env}`);
}

return configs[env];
}

async makeRequest(endpoint, data, options = {}) {
// Environment-specific pre-processing
if (this.environment === 'production') {
this.securityManager.validateProductionRequest({
headers: options.headers || {}
});
}

// Add environment-specific headers
const headers = {
...options.headers,
'X-Environment': this.environment,
...this.config.security.additionalHeaders
};

// Make request with environment-specific settings
const response = await this.executeRequest(endpoint, data, {
...options,
headers,
timeout: this.config.timeout || 30000,
retries: this.config.retry
});

// Environment-specific post-processing
return this.processResponse(response);
}

async executeRequest(endpoint, data, options) {
const url = `${this.config.baseUrl}${endpoint}`;

try {
const response = await fetch(url, {
method: 'POST',
headers: options.headers,
body: JSON.stringify(data),
timeout: options.timeout
});

return response;
} catch (error) {
if (options.retries && options.retries.maxAttempts > 1) {
return this.retryRequest(endpoint, data, options);
}
throw error;
}
}

processResponse(response) {
// Environment-specific response processing
if (this.environment === 'sandbox') {
// Add debug information in sandbox
response.debugInfo = {
environment: 'sandbox',
timestamp: new Date().toISOString(),
rateLimitRemaining: response.headers.get('X-RateLimit-Remaining')
};
}

return response;
}
}

Environment Switching

class EnvironmentManager {
constructor() {
this.clients = new Map();
}

getClient(environment) {
if (!this.clients.has(environment)) {
this.clients.set(environment, new RBIHEnvironmentClient(environment));
}

return this.clients.get(environment);
}

async promoteToProduction(testResults) {
// Validate test results before promotion
if (!this.validateTestResults(testResults)) {
throw new Error('Test validation failed');
}

// Switch to production client
const prodClient = this.getClient('production');

// Perform production readiness checks
await this.performProductionChecks(prodClient);

return prodClient;
}

validateTestResults(results) {
const requiredTests = [
'authentication',
'apiEndpoints',
'errorHandling',
'rateLimit'
];

return requiredTests.every(test =>
results[test] && results[test].passed
);
}

async performProductionChecks(client) {
// Health check
await client.healthCheck();

// Credentials validation
await client.validateCredentials();

// Rate limit verification
await client.verifyRateLimits();

console.log('Production readiness checks passed');
}
}

Migration Strategy

Sandbox to Production

const migrationChecklist = {
credentials: {
description: 'Update credentials for production',
items: [
'Replace sandbox client ID and secret',
'Update provider codes if different',
'Configure production signing secrets',
'Update IP whitelisting for production IPs'
]
},

configuration: {
description: 'Update configuration settings',
items: [
'Change base URLs to production endpoints',
'Update token validity expectations',
'Adjust rate limiting parameters',
'Configure production logging levels'
]
},

testing: {
description: 'Production validation testing',
items: [
'Verify authentication with production credentials',
'Test critical API endpoints',
'Validate error handling',
'Confirm webhook endpoints'
]
},

monitoring: {
description: 'Set up production monitoring',
items: [
'Configure health checks',
'Set up alerting for failures',
'Implement performance monitoring',
'Enable audit logging'
]
}
};

class MigrationValidator {
constructor() {
this.checklist = migrationChecklist;
}

async validateMigration() {
const results = {};

for (const [section, config] of Object.entries(this.checklist)) {
results[section] = await this.validateSection(section, config);
}

return this.generateMigrationReport(results);
}

async validateSection(section, config) {
console.log(`Validating ${section}: ${config.description}`);

// Implementation would validate each item
const validation = {
passed: true,
items: config.items.map(item => ({
description: item,
status: 'pending' // Would be 'passed' or 'failed'
}))
};

return validation;
}

generateMigrationReport(results) {
const allPassed = Object.values(results)
.every(section => section.passed);

return {
readyForProduction: allPassed,
sections: results,
recommendations: this.getRecommendations(results)
};
}

getRecommendations(results) {
const recommendations = [];

if (!results.monitoring?.passed) {
recommendations.push('Set up comprehensive monitoring before going live');
}

if (!results.testing?.passed) {
recommendations.push('Complete all production validation tests');
}

return recommendations;
}
}

This environment configuration guide ensures smooth development, testing, and production deployment while maintaining security and compliance standards across all environments.