Market API
The Market API allows you to query available markets, currencies, and regional settings for your ecommerce application.
Overview
The market module provides methods to:
- 🌍 Get available markets - Retrieve all supported markets/regions
- 💱 Query currencies - Get supported currencies per market
- 📍 Regional settings - Access market-specific configurations
- 🚀 Localization support - Handle multi-market applications
Get Available Markets
Retrieve all markets where your ecommerce store operates.
Method
Get Markets
Future<List<Market>> getAvailable()
Example
lib/services/market_service.dart
import 'package:your_app/services/sdk_service.dart';
class MarketService {
static Future<List<Market>> getAvailableMarkets() async {
try {
final markets = await SdkService().sdk.market.getAvailable();
print('Found ${markets.length} available markets');
for (final market in markets) {
print('Market: ${market.name} (${market.code})');
print('Currency: ${market.currency}');
print('Active: ${market.isActive}');
}
return markets;
} catch (e) {
print('Error fetching markets: $e');
return [];
}
}
}
Response Format
Market Model
class Market {
final String id;
final String code; // 'US', 'EU', 'CA'
final String name; // 'United States', 'Europe', 'Canada'
final String currency; // 'USD', 'EUR', 'CAD'
final String currencySymbol; // '$', '€', 'C$'
final bool isActive;
final String timezone; // 'America/New_York'
final String locale; // 'en-US', 'es-ES'
final List<String> languages; // ['en', 'es']
final Map<String, dynamic> settings;
// Convert to JSON
Map<String, dynamic> toJson();
}
Market Selection Widget
Create a widget to let users select their market:
lib/widgets/market_selector.dart
class MarketSelector extends StatefulWidget {
final Function(Market) onMarketChanged;
final Market? selectedMarket;
const MarketSelector({
super.key,
required this.onMarketChanged,
this.selectedMarket,
});
_MarketSelectorState createState() => _MarketSelectorState();
}
class _MarketSelectorState extends State<MarketSelector> {
List<Market> _markets = [];
bool _isLoading = true;
void initState() {
super.initState();
_loadMarkets();
}
Future<void> _loadMarkets() async {
try {
final markets = await SdkService().sdk.market.getAvailable();
setState(() {
_markets = markets;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
});
print('Error loading markets: $e');
}
}
Widget build(BuildContext context) {
if (_isLoading) {
return const CircularProgressIndicator();
}
return DropdownButton<Market>(
value: widget.selectedMarket,
hint: const Text('Select Market'),
items: _markets.map((market) {
return DropdownMenuItem<Market>(
value: market,
child: Row(
children: [
// Flag or icon
Container(
width: 24,
height: 16,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(2),
),
child: Center(
child: Text(
market.code,
style: const TextStyle(fontSize: 10),
),
),
),
const SizedBox(width: 8),
Text('${market.name} (${market.currency})'),
],
),
);
}).toList(),
onChanged: (market) {
if (market != null) {
widget.onMarketChanged(market);
}
},
);
}
}
Market-Aware Application
Build an app that adapts to different markets:
lib/providers/market_provider.dart
import 'package:flutter/material.dart';
class MarketProvider extends ChangeNotifier {
Market? _selectedMarket;
List<Market> _availableMarkets = [];
Market? get selectedMarket => _selectedMarket;
List<Market> get availableMarkets => _availableMarkets;
String get currency => _selectedMarket?.currency ?? 'USD';
String get currencySymbol => _selectedMarket?.currencySymbol ?? '\$';
Future<void> loadMarkets() async {
try {
_availableMarkets = await SdkService().sdk.market.getAvailable();
// Auto-select first market if none selected
if (_selectedMarket == null && _availableMarkets.isNotEmpty) {
_selectedMarket = _availableMarkets.first;
}
notifyListeners();
} catch (e) {
print('Error loading markets: $e');
}
}
void selectMarket(Market market) {
_selectedMarket = market;
notifyListeners();
// Save to preferences
_saveMarketPreference(market.code);
}
Future<void> _saveMarketPreference(String marketCode) async {
// Save to SharedPreferences or secure storage
print('Saving market preference: $marketCode');
}
String formatPrice(double amount) {
return '$currencySymbol${amount.toStringAsFixed(2)}';
}
}
Currency Conversion
Handle currency display and conversion:
lib/utils/currency_utils.dart
class CurrencyUtils {
static String formatPrice({
required double amount,
required Market market,
int decimalPlaces = 2,
}) {
final formatted = amount.toStringAsFixed(decimalPlaces);
return '${market.currencySymbol}$formatted';
}
static double convertCurrency({
required double amount,
required String fromCurrency,
required String toCurrency,
required Map<String, double> exchangeRates,
}) {
if (fromCurrency == toCurrency) return amount;
final rate = exchangeRates['${fromCurrency}_$toCurrency'];
if (rate == null) {
throw Exception('Exchange rate not found for $fromCurrency to $toCurrency');
}
return amount * rate;
}
}
// Usage in widgets
class PriceDisplay extends StatelessWidget {
final double price;
final Market market;
const PriceDisplay({
super.key,
required this.price,
required this.market,
});
Widget build(BuildContext context) {
return Text(
CurrencyUtils.formatPrice(amount: price, market: market),
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
);
}
}
Regional Configuration
Access market-specific settings and configurations:
lib/services/regional_service.dart
class RegionalService {
static Future<RegionalConfig> getConfig(String marketCode) async {
try {
final markets = await SdkService().sdk.market.getAvailable();
final market = markets.firstWhere((m) => m.code == marketCode);
return RegionalConfig(
market: market,
taxRate: market.settings['tax_rate'] ?? 0.0,
shippingOptions: market.settings['shipping_options'] ?? [],
paymentMethods: market.settings['payment_methods'] ?? [],
);
} catch (e) {
throw Exception('Failed to get regional config: $e');
}
}
}
class RegionalConfig {
final Market market;
final double taxRate;
final List<String> shippingOptions;
final List<String> paymentMethods;
RegionalConfig({
required this.market,
required this.taxRate,
required this.shippingOptions,
required this.paymentMethods,
});
}
Market Detection
Automatically detect user's market based on location:
lib/services/market_detection.dart
import 'package:geolocator/geolocator.dart';
class MarketDetection {
static Future<Market?> detectUserMarket() async {
try {
// Get user's location
final position = await Geolocator.getCurrentPosition();
// Get available markets
final markets = await SdkService().sdk.market.getAvailable();
// Simple country code detection (you might want to use a geocoding service)
final detectedCountry = await _getCountryFromCoordinates(
position.latitude,
position.longitude,
);
// Find matching market
final market = markets.firstWhere(
(m) => m.code.toLowerCase() == detectedCountry.toLowerCase(),
orElse: () => markets.first, // Fallback to first market
);
return market;
} catch (e) {
print('Error detecting market: $e');
return null;
}
}
static Future<String> _getCountryFromCoordinates(
double latitude,
double longitude,
) async {
// Implement geocoding logic or use a service like Google Geocoding
// For demo purposes, return 'US'
return 'US';
}
}
Market Filtering
Filter products and content based on selected market:
lib/services/market_filter.dart
class MarketFilter {
static List<Product> filterProductsByMarket(
List<Product> products,
Market market,
) {
return products.where((product) {
// Check if product is available in this market
final availableMarkets = product.availableMarkets ?? [];
return availableMarkets.isEmpty || availableMarkets.contains(market.code);
}).toList();
}
static Future<List<Product>> getMarketProducts(Market market) async {
try {
final allProducts = await SdkService().sdk.channel.product.get(
currency: market.currency,
market: market.code,
);
return filterProductsByMarket(allProducts, market);
} catch (e) {
print('Error getting market products: $e');
return [];
}
}
}
Error Handling
Handle market-related errors:
Market Error Handling
Future<void> handleMarketErrors() async {
try {
final markets = await SdkService().sdk.market.getAvailable();
// Process markets...
} on MarketException catch (e) {
switch (e.type) {
case MarketErrorType.noMarketsAvailable:
print('No markets are currently available');
break;
case MarketErrorType.marketNotSupported:
print('Selected market is not supported');
break;
case MarketErrorType.currencyNotSupported:
print('Currency not supported in this market');
break;
default:
print('Market error: ${e.message}');
}
} catch (e) {
print('General error: $e');
}
}
Best Practices
1. Cache Market Data
Market Caching
class MarketCache {
static List<Market>? _cachedMarkets;
static DateTime? _lastFetch;
static Future<List<Market>> getMarkets() async {
final now = DateTime.now();
// Cache for 1 hour
if (_cachedMarkets != null &&
_lastFetch != null &&
now.difference(_lastFetch!).inHours < 1) {
return _cachedMarkets!;
}
_cachedMarkets = await SdkService().sdk.market.getAvailable();
_lastFetch = now;
return _cachedMarkets!;
}
}
2. Persist Market Selection
Market Persistence
import 'package:shared_preferences/shared_preferences.dart';
class MarketPreferences {
static const String _marketKey = 'selected_market';
static Future<void> saveMarket(Market market) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_marketKey, market.code);
}
static Future<Market?> getSavedMarket() async {
final prefs = await SharedPreferences.getInstance();
final marketCode = prefs.getString(_marketKey);
if (marketCode != null) {
final markets = await MarketCache.getMarkets();
return markets.firstWhere(
(m) => m.code == marketCode,
orElse: () => markets.first,
);
}
return null;
}
}
Related APIs
- Channel API - Get market-specific products and categories
- Cart API - Create carts with market currency
- Payment API - Process payments in market currency
Troubleshooting
Common Issues
-
"No markets available"
- Check your API key permissions
- Verify your account has markets configured
-
"Currency not supported"
- Ensure the market supports the requested currency
- Check currency codes are correctly formatted
-
"Market detection failed"
- Verify location permissions are granted
- Implement fallback to default market
-
"Products not showing"
- Check if products are available in selected market
- Verify market filtering logic