Skip to main content

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;
}
}

  • 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

  1. "No markets available"

    • Check your API key permissions
    • Verify your account has markets configured
  2. "Currency not supported"

    • Ensure the market supports the requested currency
    • Check currency codes are correctly formatted
  3. "Market detection failed"

    • Verify location permissions are granted
    • Implement fallback to default market
  4. "Products not showing"

    • Check if products are available in selected market
    • Verify market filtering logic