Access real-time pricing information with multi-currency support and price change tracking using the Products V2 API.
Dynamic pricing information allows you to access accurate, up-to-date pricing information across your product catalog. The Products V2 API provides powerful tools for accessing real-time pricing information, multi-currency support, and price change tracking.
Access real-time price information for individual products:
class PriceInformationAccessor {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.joinsherpa.io/v2/products';
}
// Get product pricing information
async getProductPricing(productId, currency = 'USD') {
try {
const response = await fetch(`${this.baseUrl}/${productId}?currency=${currency}`, {
method: 'GET',
headers: {
'x-api-key': `${this.apiKey}`,
},
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`API Error: ${errorData.message}`);
}
const product = await response.json();
console.log(`Pricing for product ${productId}:`, product.pricing);
return product.pricing;
} catch (error) {
console.error(`Failed to get pricing for ${productId}:`, error.message);
throw error;
}
}
// Get government fee information
async getGovernmentFee(productId, currency = 'USD') {
const pricing = await this.getProductPricing(productId, currency);
return pricing.breakdown?.find(fee => fee.type === 'GOVERNMENT_FEE');
}
// Get service fee information
async getServiceFee(productId, currency = 'USD') {
const pricing = await this.getProductPricing(productId, currency);
return pricing.breakdown?.find(fee => fee.type === 'APPLICATION_SERVICE_FEE');
}
// Get all fee types
async getAllFees(productId, currency = 'USD') {
const pricing = await this.getProductPricing(productId, currency);
return pricing.breakdown || [];
}
}
// Usage examples
const priceAccessor = new PriceInformationAccessor('YOUR_API_KEY');
// Get government fee information
priceAccessor.getGovernmentFee('turkey-evisa-tourism', 'USD')
.then(fee => {
console.log('Government fee:', fee);
});
// Get service fee information
priceAccessor.getServiceFee('turkey-evisa-tourism', 'USD')
.then(fee => {
console.log('Service fee:', fee);
});
// Get all fees
priceAccessor.getAllFees('turkey-evisa-tourism', 'USD')
.then(fees => {
console.log('All fees:', fees);
});Access price information for multiple products:
class BulkPriceAccessor {
constructor(priceAccessor) {
this.priceAccessor = priceAccessor;
}
// Get government fees for multiple products
async getGovernmentFees(productIds, currency = 'USD') {
const results = [];
for (const productId of productIds) {
try {
const fee = await this.priceAccessor.getGovernmentFee(productId, currency);
results.push({
success: true,
productId,
fee
});
} catch (error) {
results.push({
success: false,
productId,
error: error.message
});
}
}
return results;
}
// Get service fees for multiple products
async getServiceFees(productIds, currency = 'USD') {
const results = [];
for (const productId of productIds) {
try {
const fee = await this.priceAccessor.getServiceFee(productId, currency);
results.push({
success: true,
productId,
fee
});
} catch (error) {
results.push({
success: false,
productId,
error: error.message
});
}
}
return results;
}
// Get all fees for multiple products
async getAllFeesForProducts(productIds, currency = 'USD') {
const results = [];
for (const productId of productIds) {
try {
const fees = await this.priceAccessor.getAllFees(productId, currency);
results.push({
success: true,
productId,
fees
});
} catch (error) {
results.push({
success: false,
productId,
error: error.message
});
}
}
return results;
}
}
// Usage examples
const bulkPriceAccessor = new BulkPriceAccessor(priceAccessor);
// Get government fees for multiple products
const productIds = ['turkey-evisa-tourism', 'turkey-evisa-business', 'uk-eta-tourism'];
bulkPriceAccessor.getGovernmentFees(productIds, 'USD')
.then(results => {
console.log('Government fees for products:', results);
});
// Get all fees for multiple products
bulkPriceAccessor.getAllFeesForProducts(productIds, 'USD')
.then(results => {
console.log('All fees for products:', results);
});Access pricing information in multiple currencies:
class MultiCurrencyPriceAccessor {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.joinsherpa.io/v2/products';
this.exchangeRates = new Map();
}
// Get exchange rates (mock implementation)
async getExchangeRates(baseCurrency = 'USD') {
// In a real implementation, you would fetch from an exchange rate API
const rates = {
USD: 1.0,
EUR: 0.85,
GBP: 0.73,
CAD: 1.25,
AUD: 1.35,
JPY: 110.0
};
this.exchangeRates.set(baseCurrency, rates);
return rates;
}
// Convert price to different currency
convertPrice(price, fromCurrency, toCurrency) {
if (fromCurrency === toCurrency) return price;
const rates = this.exchangeRates.get('USD');
if (!rates) throw new Error('Exchange rates not loaded');
// Convert to USD first, then to target currency
const usdPrice = fromCurrency === 'USD' ? price : price / rates[fromCurrency];
const targetPrice = toCurrency === 'USD' ? usdPrice : usdPrice * rates[toCurrency];
return Math.round(targetPrice * 100) / 100;
}
// Get product pricing in specific currency
async getProductPricingInCurrency(productId, currency) {
const response = await fetch(`${this.baseUrl}/${productId}?currency=${currency}`, {
headers: {
'Authorization': `Bearer ${this.apiToken}`,
},
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`API Error: ${errorData.message}`);
}
const product = await response.json();
return product.pricing;
}
// Get pricing in multiple currencies
async getPricingInMultipleCurrencies(productId, currencies) {
const results = [];
for (const currency of currencies) {
try {
const pricing = await this.getProductPricingInCurrency(productId, currency);
results.push({
success: true,
currency,
pricing
});
} catch (error) {
results.push({
success: false,
currency,
error: error.message
});
}
}
return results;
}
}
// Usage examples
const multiCurrencyAccessor = new MultiCurrencyPriceAccessor('YOUR_API_KEY');
// Load exchange rates
multiCurrencyAccessor.getExchangeRates()
.then(rates => {
console.log('Exchange rates loaded:', rates);
});
// Get product pricing in EUR
multiCurrencyAccessor.getProductPricingInCurrency('turkey-evisa-tourism', 'EUR')
.then(pricing => {
console.log('Product pricing in EUR:', pricing);
});
// Get pricing in multiple currencies
const currencies = ['USD', 'EUR', 'GBP', 'CAD'];
multiCurrencyAccessor.getPricingInMultipleCurrencies('turkey-evisa-tourism', currencies)
.then(results => {
console.log('Pricing in multiple currencies:', results);
});Monitor price changes and access price history:
class PriceChangeMonitor {
constructor(priceAccessor) {
this.priceAccessor = priceAccessor;
this.monitorInterval = null;
this.isRunning = false;
}
// Start price monitoring
startMonitoring(intervalMinutes = 60) {
if (this.isRunning) {
console.log('Price monitoring is already running');
return;
}
this.isRunning = true;
this.monitorInterval = setInterval(() => {
this.performMonitoring();
}, intervalMinutes * 60 * 1000);
console.log(`Price monitoring started (every ${intervalMinutes} minutes)`);
}
// Stop price monitoring
stopMonitoring() {
if (this.monitorInterval) {
clearInterval(this.monitorInterval);
this.monitorInterval = null;
this.isRunning = false;
console.log('Price monitoring stopped');
}
}
// Perform price monitoring
async performMonitoring() {
try {
console.log('Starting price monitoring...');
// Get products to monitor
const productsToMonitor = await this.getProductsToMonitor();
if (productsToMonitor.length === 0) {
console.log('No products to monitor');
return;
}
// Monitor prices for each product
const results = [];
for (const product of productsToMonitor) {
try {
const currentPricing = await this.priceAccessor.getProductPricing(product.productId);
results.push({ success: true, productId: product.productId, pricing: currentPricing });
}
} catch (error) {
results.push({ success: false, productId: product.productId, error: error.message });
}
}
console.log('Price monitoring completed:', results);
return results;
} catch (error) {
console.error('Price monitoring failed:', error);
throw error;
}
}
// Get products to monitor (mock implementation)
async getProductsToMonitor() {
// In a real implementation, you would check which products to monitor
return [
{ productId: 'turkey-evisa-tourism', lastChecked: '2024-01-01' },
{ productId: 'turkey-evisa-business', lastChecked: '2024-01-01' }
];
}
// Manual price monitoring
async manualMonitoring(productIds) {
const results = [];
for (const productId of productIds) {
try {
const currentPricing = await this.priceAccessor.getProductPricing(productId);
results.push({ success: true, productId, pricing: currentPricing });
} catch (error) {
results.push({ success: false, productId, error: error.message });
}
}
return results;
}
}
// Usage examples
const priceMonitor = new PriceChangeMonitor(priceAccessor);
// Start automated monitoring (every hour)
priceMonitor.startMonitoring(60);
// Manual monitoring
priceMonitor.manualMonitoring(['turkey-evisa-tourism', 'turkey-evisa-business'])
.then(results => {
console.log('Manual monitoring results:', results);
});
// Stop monitoring
// priceMonitor.stopMonitoring();
// Compare pricing and detect changes
const changes = this.detectPriceChanges(previousPricing, currentPricing);
if (changes.length > 0) {
const changeEvent = {
productId,
productName: product.name,
timestamp: new Date().toISOString(),
changes,
previousPricing,
currentPricing
};
// Store updated pricing
this.priceHistory.set(productId, currentPricing);
// Call callback with change event
if (callback) {
callback(changeEvent);
}
return changeEvent;
}
} else {
// First time monitoring this product
this.priceHistory.set(productId, currentPricing);
}
return null;
} catch (error) {
console.error(`Failed to monitor price changes for ${productId}:`, error);
throw error;
}
}
// Detect price changes between two pricing objects
detectPriceChanges(previousPricing, currentPricing) {
const changes = [];
const previousBreakdown = previousPricing?.breakdown || [];
const currentBreakdown = currentPricing?.breakdown || [];
// Check for changes in existing fees
previousBreakdown.forEach(prevFee => {
const currentFee = currentBreakdown.find(fee => fee.type === prevFee.type);
if (currentFee) {
if (prevFee.price !== currentFee.price) {
changes.push({
type: 'PRICE_CHANGE',
feeType: prevFee.type,
previousPrice: prevFee.price,
currentPrice: currentFee.price,
change: currentFee.price - prevFee.price,
changePercentage: ((currentFee.price - prevFee.price) / prevFee.price) * 100
});
}
} else {
changes.push({
type: 'FEE_REMOVED',
feeType: prevFee.type,
previousPrice: prevFee.price
});
}
});
// Check for new fees
currentBreakdown.forEach(currentFee => {
const prevFee = previousBreakdown.find(fee => fee.type === currentFee.type);
if (!prevFee) {
changes.push({
type: 'FEE_ADDED',
feeType: currentFee.type,
currentPrice: currentFee.price
});
}
});
return changes;
}
// Monitor multiple products
async monitorMultipleProducts(productIds, callback) {
const results = [];
for (const productId of productIds) {
try {
const changeEvent = await this.monitorProductPriceChanges(productId, callback);
if (changeEvent) {
results.push(changeEvent);
}
} catch (error) {
results.push({
productId,
error: error.message
});
}
}
return results;
}
// Get price history for a product
getPriceHistory(productId) {
return this.priceHistory.get(productId);
}
// Clear price history
clearPriceHistory(productId) {
if (productId) {
this.priceHistory.delete(productId);
} else {
this.priceHistory.clear();
}
}
}
// Usage examples
const priceMonitor = new PriceChangeMonitor('YOUR_API_KEY');
// Monitor single product
priceMonitor.monitorProductPriceChanges('turkey-evisa-tourism', (changeEvent) => {
console.log('Price change detected:', changeEvent);
// Send notification, log to database, etc.
if (changeEvent.changes.some(change => change.type === 'PRICE_CHANGE')) {
console.log('Price changed for', changeEvent.productName);
}
});
// Monitor multiple products
priceMonitor.monitorMultipleProducts(
['turkey-evisa-tourism', 'turkey-evisa-business'],
(changeEvent) => {
console.log('Price change detected:', changeEvent);
}
);`} />
## Best Practices
### Price Update Strategy
- **Validation**: Always validate price data before updates
- **Atomic Updates**: Use atomic operations for price updates
- **Error Handling**: Implement robust error handling for failed updates
- **Rollback**: Maintain ability to rollback price changes
### Performance Optimization
- **Bulk Operations**: Use bulk updates for multiple products
- **Caching**: Cache price data to reduce API calls
- **Rate Limiting**: Respect API rate limits
- **Async Processing**: Use async operations for better performance
### Data Integrity
- **Consistency**: Ensure price consistency across all products
- **Validation**: Validate price data against business rules
- **Backup**: Regularly backup price data
### Monitoring and Alerting
- **Change Detection**: Monitor for unexpected price changes
- **Alerts**: Set up alerts for significant price changes
- **Logging**: Log all price update operations
- **Metrics**: Track price update performance and success rates
<InfoCard title="💡 Pricing Tips" color="blue">
- Use bulk operations for efficient price updates
- Implement price validation to prevent invalid updates
- Monitor price changes for compliance
- Use multi-currency support for global markets
</InfoCard>
<InfoCard title="🚀 Getting Started" color="green">
Start with simple price updates and gradually implement more sophisticated
features like bulk updates and automated synchronization.
</InfoCard>