Location

Countries and states data

The Location module provides geographic data for countries and states/provinces.

Get Countries

GET /v1/operations/location/countries
SDK: sdk.location.getCountries()

Retrieve a list of all countries.

const result = await sdk.location.getCountries();

if (result.ok) {
result.val.forEach(country => {
  console.log(country.code, country.name);
  // US, United States
  // CA, Canada
  // GB, United Kingdom
  // ...
});
}

Country Response

interface Country {
  code: string;      // ISO 3166-1 alpha-2 code
  name: string;      // Full country name
  currency: string;  // ISO 4217 currency code
  phoneCode: string; // International dialing code
}

Get Country States

GET /v1/operations/location/countries/{countryCode}/states
SDK: sdk.location.getCountryStates()

Get states/provinces for a specific country.

const result = await sdk.location.getCountryStates('US');

if (result.ok) {
  result.val.forEach(state => {
    console.log(state.code, state.name);
    // AL, Alabama
    // AK, Alaska
    // AZ, Arizona
    // ...
  });
}

Parameters

Name Type Description
countryCode required string ISO 3166-1 alpha-2 country code

State Response

interface State {
  code: string; // State/province code
  name: string; // Full name
}

Use Cases

Address Form

import { useState, useEffect } from 'react';

function AddressForm() {
  const [countries, setCountries] = useState([]);
  const [states, setStates] = useState([]);
  const [selectedCountry, setSelectedCountry] = useState('');

  // Load countries on mount
  useEffect(() => {
    async function loadCountries() {
      const result = await sdk.location.getCountries();
      if (result.ok) {
        setCountries(result.val);
      }
    }
    loadCountries();
  }, []);

  // Load states when country changes
  useEffect(() => {
    async function loadStates() {
      if (!selectedCountry) {
        setStates([]);
        return;
      }

      const result = await sdk.location.getCountryStates(selectedCountry);
      if (result.ok) {
        setStates(result.val);
      }
    }
    loadStates();
  }, [selectedCountry]);

  return (
    <form>
      <select
        value={selectedCountry}
        onChange={(e) => setSelectedCountry(e.target.value)}
      >
        <option value="">Select Country</option>
        {countries.map(country => (
          <option key={country.code} value={country.code}>
            {country.name}
          </option>
        ))}
      </select>

      <select disabled={!selectedCountry}>
        <option value="">Select State</option>
        {states.map(state => (
          <option key={state.code} value={state.code}>
            {state.name}
          </option>
        ))}
      </select>
    </form>
  );
}

Shipping Calculator

async function getShippingOptions(countryCode: string, stateCode: string) {
  const countries = await sdk.location.getCountries();

  if (countries.ok) {
    const country = countries.val.find(c => c.code === countryCode);

    // Different shipping rules by region
    if (countryCode === 'US') {
      return {
        standard: 599,  // $5.99
        express: 1299,  // $12.99
        overnight: 2499 // $24.99
      };
    } else if (['CA', 'MX'].includes(countryCode)) {
      return {
        standard: 1299,
        express: 2499
      };
    } else {
      return {
        international: 2999
      };
    }
  }

  return null;
}

Tax Calculation

const US_TAX_RATES: Record<string, number> = {
  CA: 0.0725, // California 7.25%
  NY: 0.08,   // New York 8%
  TX: 0.0625, // Texas 6.25%
  // ... more states
};

async function calculateTax(
  countryCode: string,
  stateCode: string,
  amount: number
): Promise<number> {
  if (countryCode !== 'US') {
    return 0; // No US tax for international
  }

  const rate = US_TAX_RATES[stateCode] || 0;
  return Math.round(amount * rate);
}

Phone Number Formatting

async function formatPhoneInput(countryCode: string) {
  const countries = await sdk.location.getCountries();

  if (countries.ok) {
    const country = countries.val.find(c => c.code === countryCode);

    if (country) {
      return {
        placeholder: getPlaceholder(countryCode),
        prefix: `+${country.phoneCode}`,
        format: getPhoneFormat(countryCode)
      };
    }
  }

  return { placeholder: 'Phone number', prefix: '', format: null };
}

function getPlaceholder(code: string): string {
  const placeholders: Record<string, string> = {
    US: '(555) 123-4567',
    GB: '07911 123456',
    DE: '0151 12345678'
  };
  return placeholders[code] || 'Phone number';
}

Currency Display

async function getCurrencyForCountry(countryCode: string): Promise<string> {
  const countries = await sdk.location.getCountries();

  if (countries.ok) {
    const country = countries.val.find(c => c.code === countryCode);
    return country?.currency || 'USD';
  }

  return 'USD';
}

function formatPrice(amount: number, currency: string): string {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency
  }).format(amount / 100);
}

Caching

Since location data rarely changes, cache the results:

let countriesCache: Country[] | null = null;
const statesCache: Map<string, State[]> = new Map();

async function getCountries(): Promise<Country[]> {
  if (countriesCache) return countriesCache;

  const result = await sdk.location.getCountries();
  if (result.ok) {
    countriesCache = result.val;
    return countriesCache;
  }

  return [];
}

async function getStates(countryCode: string): Promise<State[]> {
  if (statesCache.has(countryCode)) {
    return statesCache.get(countryCode)!;
  }

  const result = await sdk.location.getCountryStates(countryCode);
  if (result.ok) {
    statesCache.set(countryCode, result.val);
    return result.val;
  }

  return [];
}
Tip

Cache country and state data on the client to avoid repeated API calls. This data changes infrequently.